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:
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:
Of course I can write this function myself or use a &mut bool in front, but neither are very clean solutions:
{
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
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.
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.
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.
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?
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)
to point out that method syntax can be recovered.
NLL allows overlapping mutable borrows to coexist as long as old ones are never reused.
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.)
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.
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.
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.)
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?