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).
This question is indeed interesting from a purely theoretical standpoint. Setting aside whether or not a unary, mutating boolean toggle operator would be useful, or why many languages have opted to not provide one, I ventured on a quest to see whether or not it indeed exists.
TL;DR apparently no, but Swift lets you implement one. If you'd only like to see how it's done, you can scroll to the bottom of this answer.
After a (quick) search to features of various languages, I'd feel safe to say that no language has implemented this operator as a strict mutating in-place operation (do correct me if you find one). So the next thing would be to see if there are languages that let you build one. What this would require is two things:
Many languages will immediately get ruled out for not supporting either or both of these requirements. Java for one does not allow operator overloading (or custom operators) and in addition, all primitive types are passed by value. Go has no support for operator overloading (except by hacks) whatsoever. Rust only allows operator overloading for custom types. You could almost achieve this in Scala, which let's you use very creatively named functions and also omit parentheses, but sadly there's no pass-by-reference. Fortran gets very close in that it allows for custom operators, but specifically forbids them from having inout parameters (which are allowed in normal functions and subroutines).
There is however at least one language that ticks all the necessary boxes: Swift. While some people have linked to the upcoming .toggle() member function, you can also write your own operator, which indeed supports inout arguments. Lo and behold:
prefix operator ^
prefix func ^ (b: inout Bool) {
b = !b
}
var foo = true
print(foo)
// true
^foo
print(foo)
// false