Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does any language have a unary boolean toggle operator?

People also ask

Is unary operator in Java?

Unary Operators in JavaJava unary operators are the types that need only one operand to perform any operation like increment, decrement, negation, etc. It consists of various arithmetic, logical and other operators that operate on a single operand.

What is unary and binary operator in Java?

An operator is called a unary, binary, or ternary operator based on the number of operands. If an operator takes one operand, it called a unary operator; if it takes two operands, it called a binary operator; if it takes three operands, it called a ternary operator.

What is Boolean toggle?

The expression to be executed if true is given as 'false' and expression to be executed if false is given as 'true'. The result of this operator is assigned back to the boolean value to be toggled. This will effectively toggle the value as a true condition will return false, and a false condition would return true.


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:

  • SE-0199: Adding toggle to Bool

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.


In C++ it is possible to commit the Cardinal Sin of redefining the meaning of operators. With this in mind, and a little bit of ADL, all we need to do in order to unleash mayhem on our user base is this:

#include <iostream>

namespace notstd
{
    // define a flag type
    struct invert_flag {    };

    // make it available in all translation units at zero cost
    static constexpr auto invert = invert_flag{};

    // for any T, (T << invert) ~= (T = !T)    
    template<class T>
    constexpr T& operator<<(T& x, invert_flag)
    {
        x = !x;
        return x;
    }
}

int main()
{
    // unleash Hell
    using notstd::invert;

    int a = 6;
    std::cout << a << std::endl;

    // let confusion reign amongst our hapless maintainers    
    a << invert;
    std::cout << a << std::endl;

    a << invert;
    std::cout << a << std::endl;

    auto b = false;
    std::cout << b << std::endl;

    b << invert;
    std::cout << b << std::endl;
}

expected output:

6
0
1
0
1

As long as we include assembly language...

FORTH

INVERT for a bitwise complement.

0= for a logical (true/false) complement.


Decrementing a C99 bool will have the desired effect, as will incrementing or decrementing the bit types supported in some tiny-microcontroller dialects (which from what I've observed treat bits as single-bit wide bitfields, so all even numbers get truncated to 0 and all odd numbers to 1). I wouldn't particularly recommend such usage, in part because I'm not a big fan of the bool type semantics [IMHO, the type should have specified that a bool to which any value other than 0 or 1 is stored may behave when read as though it holds an Unspecified (not necessarily consistent) integer value; if a program is trying to store an integer value that isn't known to be 0 or 1, it should use !! on it first].


Assembly language

NOT eax

See https://www.tutorialspoint.com/assembly_programming/assembly_logical_instructions.htm


I'm assuming you're not going to be choosing a language based solely upon this :-) In any case, you can do this in C++ with something like:

inline void makenot(bool &b) { b = !b; }

See the following complete program for example:

#include <iostream>

inline void makenot(bool &b) { b = !b; }

inline void outBool(bool b) { std::cout << (b ? "true" : "false") << '\n'; }

int main() {
    bool this_dataSource_trackedObject_currentValue_booleanFlag = false;
    outBool(this_dataSource_trackedObject_currentValue_booleanFlag);

    makenot(this_dataSource_trackedObject_currentValue_booleanFlag);
    outBool(this_dataSource_trackedObject_currentValue_booleanFlag);

    makenot(this_dataSource_trackedObject_currentValue_booleanFlag);
    outBool(this_dataSource_trackedObject_currentValue_booleanFlag);
}

This outputs, as expected:

false
true
false