# Idea: invert() or toggle() function for boolean type?

**URL:** <https://internals.rust-lang.org/t/idea-invert-or-toggle-function-for-boolean-type/8860>\
**Category:** Uncategorized\
**Created:** [November 19, 2018, 12:05pm UTC](https://internals.rust-lang.org/t/idea-invert-or-toggle-function-for-boolean-type/8860 "2018-11-19T12:05:10Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![sharazam](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/sharazam/32/2667_2.png) [@sharazam](https://internals.rust-lang.org/u/sharazam)\
**Post date:** [November 19, 2018, 12:05pm UTC](https://internals.rust-lang.org/t/idea-invert-or-toggle-function-for-boolean-type/8860/1 "2018-11-19T12:05:10Z")

</div>

This is a fairly small issue I have with booleans - often I want to toggle some boolean (if it’s true, set to false, if it’s false, set to true), but it happens that the boolean is fairly nested. So I have to type something like:

```rust
a_very_long_struct.my_field.my_nested_field.data.state[idx].blah = !a_very_long_struct.my_field.my_nested_field.data.state[idx].blah;

```

What I’d like to have is some kind of `.invert()` or `.toggle()` function on the boolean type itself, so I don’t have to write the whole path a second time:

```rust
a_very_long_struct.my_field.my_nested_field.data.state[idx].blah.invert();

```

Of course I can write this function myself or use a `&mut bool` in front, but neither are very clean solutions:

```rust
{
    let x = &mut a_very_long_struct.my_field.my_nested_field.data.state[idx].blah;
    *x != *x;
} // borrow checker - need to release &mut on a_very_long_struct

```

or with an external crate:

```rust
fn toggle(data: &mut bool) {
    *data != *data;
}

use my_crate::toggle;
toggle(&mut a_very_long_struct.my_field.my_nested_field.data.state[idx].blah);

```

While I can create a function like that myself, it’s a bit annoying not to have it in the standard library or implemented directly on the `bool` type, so I wanted to ask if it would be a good idea to implement this.

---

<div class="post-metadata">

**Author:** ![krdln](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/krdln/32/7081_2.png) [@krdln](https://internals.rust-lang.org/u/krdln)\
**Post date:** [November 19, 2018, 12:24pm UTC](https://internals.rust-lang.org/t/idea-invert-or-toggle-function-for-boolean-type/8860/2 "2018-11-19T12:24:10Z")

</div>

You can also do

```rust
some_bool ^= true;

```

although perhaps it’s less readable.

---

<div class="post-metadata">

**Author:** ![ExpHP](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/exphp/32/6208_2.png) [@ExpHP](https://internals.rust-lang.org/u/ExpHP)\
**Post date:** [November 19, 2018, 1:30pm UTC](https://internals.rust-lang.org/t/idea-invert-or-toggle-function-for-boolean-type/8860/3 "2018-11-19T13:30:31Z")

</div>

> [@sharazam](#):
>
> ```rust
> {
> let x = &mut a_very_long_struct.my_field.my_nested_field.data.state[idx].blah;
> *x != *x;
> } // borrow checker - need to release &mut on a_very_long_struct
> 
> ```

Thankfully NLL will remove the need for these braces in Rust 2018 Edition.

> [@sharazam](#):
>
> While I can create a function like that myself, it’s a bit annoying not to have it in the standard library or implemented directly on the `bool` type, so I wanted to ask if it would be a good idea to implement this.

You can make this a method by writing an extension trait:

```rust
trait BoolToggleExt {
    fn toggle(&mut self);
}

impl BoolToggleExt for bool {
    fn toggle(&mut self) {
        *self = !*self;
    }
}

use my_crate::BoolToggleExt;
a_very_long_struct.my_field.my_nested_field.data.state[idx].blah.toggle();

```

---

<div class="post-metadata">

**Author:** ![sharazam](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/sharazam/32/2667_2.png) [@sharazam](https://internals.rust-lang.org/u/sharazam)\
**Post date:** [November 19, 2018, 3:38pm UTC](https://internals.rust-lang.org/t/idea-invert-or-toggle-function-for-boolean-type/8860/4 "2018-11-19T15:38:21Z")

</div>

**I know that I can make my own function** , but then I have to import the trait again and I can’t reuse it inbetween projects without importing an external library. Which is why I was asking if anyone has objections to putting it in the standard library. I mean it doesn’t add much to the language complexity.

And no, NLL won’t help with the braces, since NLL can’t reason about array access. It will still think that `data.state` is borrowed. My point was, having to make an intermediate variable does not look nice.

---

<div class="post-metadata">

**Author:** ![Centril](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/centril/32/3334_2.png) [@Centril](https://internals.rust-lang.org/u/Centril)\
**Post date:** [November 19, 2018, 3:51pm UTC](https://internals.rust-lang.org/t/idea-invert-or-toggle-function-for-boolean-type/8860/6 "2018-11-19T15:51:30Z")

</div>

I don’t remember the last time I wanted a `&mut bool -> ()` operation but if this is common enough then it seems worthwhile as a standard library addition for the improved readability; `.toggle()` seems the most “boolean” sounding operation; `.flip()` might be another word for it.

---

<div class="post-metadata">

**Author:** ![Soni](https://avatars.discourse-cdn.com/v4/letter/s/a3d4f5/32.png) [@Soni](https://internals.rust-lang.org/u/Soni)\
**Post date:** [November 19, 2018, 5:54pm UTC](https://internals.rust-lang.org/t/idea-invert-or-toggle-function-for-boolean-type/8860/7 "2018-11-19T17:54:42Z")

</div>

I’ve wanted this a few times, but ended up using `Option<()>` and `take()`, so maybe `fn clear(&mut self) -> bool` and `fn set(&mut self) -> bool` would be more useful?

---

<div class="post-metadata">

**Author:** ![ExpHP](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/exphp/32/6208_2.png) [@ExpHP](https://internals.rust-lang.org/u/ExpHP)\
**Post date:** [November 20, 2018, 12:48am UTC](https://internals.rust-lang.org/t/idea-invert-or-toggle-function-for-boolean-type/8860/8 "2018-11-20T00:48:38Z")

</div>

> [@sharazam](#):
>
> **I know that I can make my own function** ,

I'm not sure if this is your intent, but your use of emphasis here comes across as extremely hostile! I _know_ that you know this. I read the post from top to bottom and back. I was responding to these specific words: (emphasis mine)

> [@](#):
>
> While I can create a function like that myself, it’s a bit annoying not to have it in the standard library **_or implemented directly on the `bool` type,_** so I wanted to ask if it would be a good idea to implement this.

to point out that method syntax can be recovered.

* * *

> [@sharazam](#):
>
> NLL won’t help with the braces,

> **[Rust Playground](https://play.rust-lang.org/?version=nightly&amp%3Bmode=debug&amp%3Bedition=2018&amp%3Bgist=b6fc456e5c45ef9074a5093dad50595b)**
>
> A browser interface to the Rust compiler to experiment with the language

NLL allows overlapping mutable borrows to coexist as long as old ones are never reused.

* * *

> [@sharazam](#):
>
> Which is why I was asking if anyone has objections to putting it in the standard library.

For me, the default answer to "should it be in the standard library" on anything I haven't previously thought about is always "no." That is why my first reply focused on specific details in your post to see if any of them changes the landscape of the problem enough for another solution to be workable. And were this not the case, my next response probably would have been something along the lines of:

_Well, I suppose there aren't an awful lot of other things that one might need to do with a `bool`, so adding a method for this seems harmless. (Modulo the color of the bike shed.)_

---

<div class="post-metadata">

**Author:** ![earthengine](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/earthengine/32/2577_2.png) [@earthengine](https://internals.rust-lang.org/u/earthengine)\
**Post date:** [November 20, 2018, 1:29am UTC](https://internals.rust-lang.org/t/idea-invert-or-toggle-function-for-boolean-type/8860/9 "2018-11-20T01:29:27Z")

</div>

> [@krdln](#):
>
> You can also do
> 
> ```rust
> some_bool ^= true;
> 
> ```
> 
> although perhaps it’s less readable.

or you can use the explicit form

```rust
some_bool.bitxor_assign(true);

```

---

<div class="post-metadata">

**Author:** ![Centril](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/centril/32/3334_2.png) [@Centril](https://internals.rust-lang.org/u/Centril)\
**Post date:** [November 20, 2018, 5:14am UTC](https://internals.rust-lang.org/t/idea-invert-or-toggle-function-for-boolean-type/8860/10 "2018-11-20T05:14:57Z")

</div>

> [@earthengine](#):
>
> or you can use the explicit form
> 
> ```rust
> some_bool.bitxor_assign(true);
> 
> ```

That seems less readable than

```rust
some_bool.toggle();

```

the intent signaled is quite different. With the former I have to stop and think "ah, this is just flipping the truthiness" and with the latter there's no thinking.

---

<div class="post-metadata">

**Author:** ![tspiteri](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/tspiteri/32/7283_2.png) [@tspiteri](https://internals.rust-lang.org/u/tspiteri)\
**Post date:** [November 20, 2018, 9:27am UTC](https://internals.rust-lang.org/t/idea-invert-or-toggle-function-for-boolean-type/8860/11 "2018-11-20T09:27:14Z")

</div>

For all integer primitives and for `bool`, currently `bitand`, `bitor` and `bitxor` have counterparts `bitand_assign`, `bitor_assign` and `bitxor_assign` but `not` does not have a counterpart. This is probably because there are `&=`, `|=` and `^=` operators but no operator for bitwise inversion of `self`.

An `invert` or `toggle` function would be a counterpart to `not`, though there is no operator. I think `invert` is better than `toggle` as it can be applied to integers as well as `bool`, where it can be useful too though not as much as for `bool`.

---

<div class="post-metadata">

**Author:** ![tspiteri](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/tspiteri/32/7283_2.png) [@tspiteri](https://internals.rust-lang.org/u/tspiteri)\
**Post date:** [November 20, 2018, 9:29am UTC](https://internals.rust-lang.org/t/idea-invert-or-toggle-function-for-boolean-type/8860/12 "2018-11-20T09:29:31Z")

</div>

> [@sharazam](#):
>
> \*x != \*x;

I think you mean `*x = !*x;`

> [@sharazam](#):
>
> \*data != \*data;

And `*data = !*data;`

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [November 20, 2018, 4:06pm UTC](https://internals.rust-lang.org/t/idea-invert-or-toggle-function-for-boolean-type/8860/13 "2018-11-20T16:06:39Z")

</div>

> [@Centril](#):
>
> With the former I have to stop and think “ah, this is just flipping the truthiness” and with the latter there’s no thinking.

I find `^= true` more readable than `.toggle()`, personally. I've been using that for years in multiple different languages, and don't see the need to invent a name for it that ends up being longer anyway. (Particularly since there's no usable chaining that can be involved here.)

---

<div class="post-metadata">

**Author:** ![Centril](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/centril/32/3334_2.png) [@Centril](https://internals.rust-lang.org/u/Centril)\
**Post date:** [November 20, 2018, 6:08pm UTC](https://internals.rust-lang.org/t/idea-invert-or-toggle-function-for-boolean-type/8860/14 "2018-11-20T18:08:26Z")

</div>

That’s fair; I don’t do much bitwise operations so when I see `^= true` I still have to wait and think about the `true` here. I suspect that you do these kind of operations more than me so you are more used to it?

---

<div class="post-metadata">

**Author:** ![nikomatsakis](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nikomatsakis/32/5410_2.png) [@nikomatsakis](https://internals.rust-lang.org/u/nikomatsakis)\
**Post date:** [November 20, 2018, 6:12pm UTC](https://internals.rust-lang.org/t/idea-invert-or-toggle-function-for-boolean-type/8860/15 "2018-11-20T18:12:17Z")

</div>

> [@Centril](#):
>
> it seems worthwhile as a standard library addition for the improved readability

I'm not sure about toggling _exactly_ but there are a few similar "convenience methods" I've wanted in the past (and some random names):

- `reset` -- equivalent to `mem::replace(path, false)`. I often want to do something like `while dirty.reset() {... dirty = true; ...}`
- `increment` -- equivalent to `fetch_add(1, Ordering::SeqCst)` but for ordinary integers, not atomic ones

Similar to the poster here, I've never _quite_ felt sufficiently motivated to make a helper library for these.

---

<div class="post-metadata">

**Author:** ![nikomatsakis](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nikomatsakis/32/5410_2.png) [@nikomatsakis](https://internals.rust-lang.org/u/nikomatsakis)\
**Post date:** [November 20, 2018, 6:12pm UTC](https://internals.rust-lang.org/t/idea-invert-or-toggle-function-for-boolean-type/8860/16 "2018-11-20T18:12:58Z")

</div>

For that matter, I would like to have a method `not` that is equivalent to `!x`, just because prefix operators are annoying. =)

---

<div class="post-metadata">

**Author:** ![Centril](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/centril/32/3334_2.png) [@Centril](https://internals.rust-lang.org/u/Centril)\
**Post date:** [November 20, 2018, 6:13pm UTC](https://internals.rust-lang.org/t/idea-invert-or-toggle-function-for-boolean-type/8860/17 "2018-11-20T18:13:42Z")

</div>

> [@nikomatsakis](#):
>
> For that matter, I would like to have a method `not` that is equivalent to `!x` , just because prefix operators are annoying. =)

[Not in std::ops - Rust](https://doc.rust-lang.org/nightly/std/ops/trait.Not.html#tymethod.not) 😛

Long live the post-fix operators!

---

<div class="post-metadata">

**Author:** ![mcy](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/mcy/32/6512_2.png) [@mcy](https://internals.rust-lang.org/u/mcy)\
**Post date:** [November 20, 2018, 6:14pm UTC](https://internals.rust-lang.org/t/idea-invert-or-toggle-function-for-boolean-type/8860/18 "2018-11-20T18:14:32Z")

</div>

> [@scottmcm](#):
>
> multiple different languages,

What other languages given you `^` as a first-class thing for bools? I've _never_ seen this before (beyond using `!=` for bools as a hacky version thereof).

---

<div class="post-metadata">

**Author:** ![CAD97](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cad97/32/3460_2.png) [@CAD97](https://internals.rust-lang.org/u/CAD97)\
**Post date:** [November 20, 2018, 7:20pm UTC](https://internals.rust-lang.org/t/idea-invert-or-toggle-function-for-boolean-type/8860/19 "2018-11-20T19:20:10Z")

</div>

Almost every language I know (that I picked out on TIO in a quick pass through) offered boolean xor via `^`:

- C (`stdbool.h`): [Try it online!](https://tio.run/##VYxBDoMgFET3nGLyGxNNqgeQtt6kyQfRklBoBFdNz47QnbN7byaje@3Yr/livXb7bHCLabZheD3ESakQXJXC@oQ3W992@OZqwbgjbbuR4o/qjLog4wklM0o@WzlYWqq6iXQt/QSqe8IIWthFQ50Uv3wA "C (clang) – Try It Online")
- C#: [Try it online!](https://tio.run/##VcqxCsIwFEbhPU/x06kFFffg5NzJwaEopNdQAjEXcm8FCXn2WN0cP84h2RNn31YJacHlLeqf1hiKTgQjihF1GggvDg@MLqReNG/rdIPLiwwobWaOcDhB8@qt@XH@J210uGO27cxJOPrDNQf1ffct5Vi7HWiwptb2AQ "C# (.NET Core) – Try It Online")
- C++: [Try it online!](https://tio.run/##VctBDsIgFIThPaeYPDftwgsA6k1MHq9oSCg0BVbGs6N01918mfyybVeJnN79EpLEtnjYkEvdPa93pUKqWDmkacanu5wjGDfUvXmjDroz5U/GE870UhetJbcKa0HjoLEmwQM0EoIGvTgWT7NR3/4D "C++ (clang) – Try It Online")
- Haskell: omitted because I don’t know it well enough to bang out a TIO example
- Java: [Try it online!](https://tio.run/##ZcxLCsIwFIXheVZxKQgNaDYQXIKjDkXhJo0lNY@S3BSkdO0xgo4cHfg4/DOueIqLCfP4rNphznCBjS1FOashE1KbNdoRPNrQD5RsmK43wDRlDltVMTqDARDOQKkYyX6i/kQ3QbiDknV4ZTJexEJiaUX6hsUjJo/Ud5/rQXVH0JxLtu/1DQ "Java (OpenJDK 8) – Try It Online")
- JavaScript (cooerce to `number`): [Try it online!](https://tio.run/##y0osSyxOLsosKNHNy09J/f8/J7VEIVHBVqGkqDTVmgvES0LhJQN5iQpxCknW/5Pz84rzc1L1cvLTNZSA4ko6Csma1lwowiWVBan5aRrJmmBpOE/T@j8A "JavaScript (Node.js) – Try It Online")
- Kotlin: no, [Try it online!](https://tio.run/##y84vycnM@59WmqeQm5iZp6GpUP2/LDFHIVHBVqGkqDSVC8RJQuYkAzmJChX5RQpJ/wuKMvNKcvI0gkuAjHS9tPyi3MQSDSWQEtUkJR2FZE1Nrtr/AA "Kotlin – Try It Online")
- Python: [Try it online!](https://tio.run/##K6gsycjPM/7/P1HBViGkqDSVKwnGSAYyEhXiFJL@FxRl5pVoKAEFlHQUkjX/AwA "Python 3 – Try It Online")
- Rust: [Try it online!](https://tio.run/##KyotLvmflqeQm5iZp6GpUP0/J7VEIVHBVqGkqDTVmgvES0LhJQN5iQpxCknW/wuKMvNKFDWUQELVtUo6CsmaXLX/AQ "Rust – Try It Online")
- Swift: no, [Try it online!](https://tio.run/##Ky7PTCsx@Z9WmpeskJuYmaehqVD9Pye1RCFRwVahpKg01ZoLxEtC4SUDeYkKcQpJ1v8LijLzSjSUQCLVtUo6CsmaXLX/AQ "Swift 4 – Try It Online")

---

<div class="post-metadata">

**Author:** ![mcy](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/mcy/32/6512_2.png) [@mcy](https://internals.rust-lang.org/u/mcy)\
**Post date:** [November 20, 2018, 7:28pm UTC](https://internals.rust-lang.org/t/idea-invert-or-toggle-function-for-boolean-type/8860/20 "2018-11-20T19:28:46Z")

</div>

My entire life has been a lie.

---

<div class="post-metadata">

**Author:** ![mbrubeck](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/mbrubeck/32/174_2.png) [@mbrubeck](https://internals.rust-lang.org/u/mbrubeck)\
**Post date:** [November 20, 2018, 7:32pm UTC](https://internals.rust-lang.org/t/idea-invert-or-toggle-function-for-boolean-type/8860/21 "2018-11-20T19:32:04Z")

</div>

> [@nikomatsakis](#):
>
> `increment` – equivalent to `fetch_add(1, Ordering::SeqCst)` but for ordinary integers, not atomic ones

`x.add_assign(1)` (or `x += 1`) seem like reasonable approximations in this case.

If we had an `increment` method then people would want a `++` operator to go with it. 🙂

[Next page](https://internals.rust-lang.org/t/idea-invert-or-toggle-function-for-boolean-type/8860.md?page=2)
