Does any language have a unary boolean toggle operator?

CompuChip picture CompuChip · Aug 20, 2018 · Viewed 10.6k times · Source

So this is more of a theoretical question. C++ and languages (in)directly based on it (Java, C#, PHP) have shortcut operators for assigning the result of most binary operators to the first operand, such as

a += 3;   // for a = a + 3
a *= 3;   // for a = a * 3;
a <<= 3;  // for a = a << 3;

but when I want to toggle a boolean expression I always find myself writing something like

a = !a;

which gets annoying when a is a long expression like.

this.dataSource.trackedObject.currentValue.booleanFlag =
    !this.dataSource.trackedObject.currentValue.booleanFlag;

(yeah, Demeter's Law, I know).

So I was wondering, is there any language with a unary boolean toggle operator that would allow me to abbreviate a = !a without repeating the expression for a, for example

!=a;  
// or
a!!;

Let's assume that our language has a proper boolean type (like bool in C++) and that a is of that type (so no C-style int a = TRUE).

If you can find a documented source, I'd also be interested to learn whether e.g. the C++ designers have considered adding an operator like that when bool became a built-in type and if so, why they decided against it.


(Note: I know that some people are of the opinion that assignment should not use = and that ++ and += are not useful operators but design flaws; let's just assume I'm happy with them and focus on why they would not extend to bools).

Answer

dfrib picture dfrib · Aug 20, 2018

Toggling the boolean bit

... that would allow me to abbreviate a = !a without repeating the expression for a ...

This approach is not really a pure "mutating flip" operator, but does fulfill your criteria above; the right hand side of the expression does not involve the variable itself.

Any language with a boolean XOR assignment (e.g. ^=) would allow flipping the current value of a variable, say a, by means of XOR assignment to true:

// type of a is bool
a ^= true;  // if a was false, it is now true,
            // if a was true, it is now false

As pointed out by @cmaster in the comments below, the above assumes a is of type bool, and not e.g. an integer or a pointer. If a is in fact something else (e.g. something non-bool evaluating to a "truthy" or "falsy" value, with a bit representation that is not 0b1 or 0b0, respectively), the above does not hold.

For a concrete example, Java is a language where this is well-defined and not subject to any silent conversions. Quoting @Boann's comment from below:

In Java, ^ and ^= have explicitly defined behavior for booleans and for integers (15.22.2. Boolean Logical Operators &, ^, and | ), where either both sides of the operator must be booleans, or both sides must be integers. There's no silent conversion between those types. So it's not going to silently malfunction if a is declared as an integer, but rather, give a compile error. So a ^= true; is safe and well-defined in Java.


Swift: toggle()

As of Swift 4.2, the following evolution proposal has been accepted and implemented:

This adds a native toggle() function to the Bool type in Swift.

toggle()

Toggles the Boolean variable’s value.

Declaration

mutating func toggle()

Discussion

Use this method to toggle a Boolean value from true to false or from false to true.

var bools = [true, false]

bools[0].toggle() // bools == [false, false]

This is not an operator, per se, but does allow a language native approach for boolean toggling.