Does any language have a unary boolean toggle operator?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
110
down vote

favorite
12












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).







share|improve this question


















  • 27




    What about a function void Flip(bool& Flag) Flag=!Flag; The shortens your long expression.
    – harper
    Aug 20 at 8:50






  • 62




    this.dataSource.trackedObject.currentValue.booleanFlag ^= 1;
    – Kamil Cuk
    Aug 20 at 8:51






  • 10




    long expressions can be assigned to references to simplify the code
    – Quentin 2
    Aug 20 at 8:51






  • 3




    @KamilCuk This might work, but you mixup types. You assign an integer to an bool.
    – harper
    Aug 20 at 8:52







  • 3




    @user463035818 there is *= -1 though, which for some reason I find more intuitive than ^= true.
    – CompuChip
    Aug 20 at 9:07














up vote
110
down vote

favorite
12












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).







share|improve this question


















  • 27




    What about a function void Flip(bool& Flag) Flag=!Flag; The shortens your long expression.
    – harper
    Aug 20 at 8:50






  • 62




    this.dataSource.trackedObject.currentValue.booleanFlag ^= 1;
    – Kamil Cuk
    Aug 20 at 8:51






  • 10




    long expressions can be assigned to references to simplify the code
    – Quentin 2
    Aug 20 at 8:51






  • 3




    @KamilCuk This might work, but you mixup types. You assign an integer to an bool.
    – harper
    Aug 20 at 8:52







  • 3




    @user463035818 there is *= -1 though, which for some reason I find more intuitive than ^= true.
    – CompuChip
    Aug 20 at 9:07












up vote
110
down vote

favorite
12









up vote
110
down vote

favorite
12






12





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).







share|improve this question














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).









share|improve this question













share|improve this question




share|improve this question








edited Aug 20 at 11:20

























asked Aug 20 at 8:46









CompuChip

6,51431542




6,51431542







  • 27




    What about a function void Flip(bool& Flag) Flag=!Flag; The shortens your long expression.
    – harper
    Aug 20 at 8:50






  • 62




    this.dataSource.trackedObject.currentValue.booleanFlag ^= 1;
    – Kamil Cuk
    Aug 20 at 8:51






  • 10




    long expressions can be assigned to references to simplify the code
    – Quentin 2
    Aug 20 at 8:51






  • 3




    @KamilCuk This might work, but you mixup types. You assign an integer to an bool.
    – harper
    Aug 20 at 8:52







  • 3




    @user463035818 there is *= -1 though, which for some reason I find more intuitive than ^= true.
    – CompuChip
    Aug 20 at 9:07












  • 27




    What about a function void Flip(bool& Flag) Flag=!Flag; The shortens your long expression.
    – harper
    Aug 20 at 8:50






  • 62




    this.dataSource.trackedObject.currentValue.booleanFlag ^= 1;
    – Kamil Cuk
    Aug 20 at 8:51






  • 10




    long expressions can be assigned to references to simplify the code
    – Quentin 2
    Aug 20 at 8:51






  • 3




    @KamilCuk This might work, but you mixup types. You assign an integer to an bool.
    – harper
    Aug 20 at 8:52







  • 3




    @user463035818 there is *= -1 though, which for some reason I find more intuitive than ^= true.
    – CompuChip
    Aug 20 at 9:07







27




27




What about a function void Flip(bool& Flag) Flag=!Flag; The shortens your long expression.
– harper
Aug 20 at 8:50




What about a function void Flip(bool& Flag) Flag=!Flag; The shortens your long expression.
– harper
Aug 20 at 8:50




62




62




this.dataSource.trackedObject.currentValue.booleanFlag ^= 1;
– Kamil Cuk
Aug 20 at 8:51




this.dataSource.trackedObject.currentValue.booleanFlag ^= 1;
– Kamil Cuk
Aug 20 at 8:51




10




10




long expressions can be assigned to references to simplify the code
– Quentin 2
Aug 20 at 8:51




long expressions can be assigned to references to simplify the code
– Quentin 2
Aug 20 at 8:51




3




3




@KamilCuk This might work, but you mixup types. You assign an integer to an bool.
– harper
Aug 20 at 8:52





@KamilCuk This might work, but you mixup types. You assign an integer to an bool.
– harper
Aug 20 at 8:52





3




3




@user463035818 there is *= -1 though, which for some reason I find more intuitive than ^= true.
– CompuChip
Aug 20 at 9:07




@user463035818 there is *= -1 though, which for some reason I find more intuitive than ^= true.
– CompuChip
Aug 20 at 9:07












13 Answers
13






active

oldest

votes

















up vote
121
down vote













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.






share|improve this answer






















  • Comments are not for extended discussion; this conversation has been moved to chat.
    – Samuel Liew♦
    Aug 20 at 23:03

















up vote
30
down vote













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





share|improve this answer
















  • 6




    “the Cardinal Sin of redefining the meaning of operators” — I get that you were exaggerating but it’s really not a cardinal sin to reassign new meanings to existing operators in general.
    – Konrad Rudolph
    Aug 20 at 10:05






  • 3




    @KonradRudolph What I mean by this of course that an operator should make logical sense with respect to its usual arithmetic or logical meaning. 'operator+` for 2 strings is logical, since concatenation is similar (in our mind's eye) to addition or accumulation. operator<< has come to mean 'streamed out' because of its original abuse in the STL. It will not naturally mean 'apply the transform function on the RHS', which is essentially what I have re-purposed it for here.
    – Richard Hodges
    Aug 20 at 10:11






  • 3




    I don’t think that’s a good argument, sorry. First off, string concatenation has completely different semantics from addition (it isn’t even commutative!). Secondly, by your logic << is a bit shift operator, not a “stream out” operator. The problem with your redefinition isn’t that it’s inconsistent with existing meanings of the operator, but rather that it adds no value over a simple function call.
    – Konrad Rudolph
    Aug 20 at 11:05






  • 6




    << seems like a bad overload. I'd do !invert= x; ;)
    – Yakk - Adam Nevraumont
    Aug 20 at 16:04






  • 10




    @Yakk-AdamNevraumont LOL, now you've got me started: godbolt.org/z/KIkesp
    – Richard Hodges
    Aug 20 at 17:17

















up vote
26
down vote













As long as we include assembly language...



FORTH



INVERT for a bitwise complement.



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






share|improve this answer
















  • 1




    Arguable, in every stack-oriented language an unary not is a "toggle" operator :-)
    – Bergi
    Aug 21 at 16:28










  • Sure, it's a bit of a sideways answer as the OP is clearly thinking about C-like languages that have a traditional assignment statement. I think sideways answers like this have value, if only to show a part of the programming world that the reader might not have thought of. ("There are more programming languages in heaven and earth, Horatio, than are dreampt of in our philosophy.")
    – Wayne Conrad
    Aug 21 at 17:51


















up vote
22
down vote













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].






share|improve this answer




















  • C++ did the same thing with bool until C++17.
    – Davis Herring
    Aug 22 at 1:02

















up vote
22
down vote













Assembly language



NOT eax


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






share|improve this answer




















  • I don't think this is quite what op had in mind, assuming this is x86 assembly. e.g. en.wikibooks.org/wiki/X86_Assembly/Logic ; here edx would be 0xFFFFFFFE because a bitwise NOT 0x00000001 = 0xFFFFFFFE
    – BurnsBA
    Aug 20 at 19:31







  • 5




    You can use all bits instead: NOT 0x00000000 = 0xFFFFFFFF
    – 4dr14n31t0r Th3 G4m3r
    Aug 20 at 19:33







  • 2




    Well, yes, though I was trying to the draw the distinction between boolean and bitwise operators. As op says in the question, assume the language has a well-defined boolean type: "(so no C-style int a = TRUE)."
    – BurnsBA
    Aug 21 at 12:22






  • 2




    @BurnsBA: indeed, assembly languages don't have a single set of well-defined truthy / falsy values. Over on code-golf, much has been discussed about which values you're allowed to return for boolean problems in various languages. Since asm doesn't have an if(x) construct, it's totally reasonable to allow 0 / -1 as false/true, like for SIMD compares (felixcloutier.com/x86/PCMPEQB:PCMPEQW:PCMPEQD.html). But you're right that this breaks if you use it on any other value.
    – Peter Cordes
    Aug 21 at 12:53






  • 1




    It's hard to have a single Boolean representation given that PCMPEQW results in 0/-1, but SETcc results in 0/+1.
    – Eugene Styer
    Aug 21 at 14:11

















up vote
19
down vote













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





share|improve this answer






















  • Would you want to return b = !b as well? Someone reading foo = makenot(x) || y or just a simple foo = makenot(bar) might assume that makenot was a pure function, and assume there was no side-effect. Burying a side-effect inside a larger expression is probably bad style, and the only benefit of a non-void return type is enabling that.
    – Peter Cordes
    Aug 21 at 12:32










  • @MatteoItalia suggests template<typename T> T& invert(T& t) t = !t; return t; , which being templated will convert to/from bool if used on a non-bool object. IDK if that's good or bad. Presumably good.
    – Peter Cordes
    Aug 21 at 12:34

















up vote
16
down vote













PostScript, being a concatenative, stack-oriented language like Forth, has a unary toggle, not. The not operator toggles the value on top of the stack. For example,



true % push true onto the stack
not % invert the top of stack
% the top of stack is now false


See the PostScript Language Reference Manual (pdf), p. 458.






share|improve this answer





























    up vote
    13
    down vote













    Visual Basic.Net supports this via an extension method.



    Define the extension method like so:



    <Extension>
    Public Sub Flip(ByRef someBool As Boolean)
    someBool = Not someBool
    End Sub


    And then call it like this:



    Dim someVariable As Boolean
    someVariable = True
    someVariable.Flip


    So, your original example would look something like:



    me.DataSource.TrackedObject.CurrentValue.BooleanFlag.Flip





    share|improve this answer
















    • 1




      While this does function as the shorthand the author was seeking, of course, you must use two operators to implement Flip(): = and Not. It's interesting to learn that in the case of calling SomeInstance.SomeBoolean.Flip it works even if SomeBoolean is a property, whereas the equivalent C# code would not compile.
      – BACON
      Aug 21 at 5:53

















    up vote
    8
    down vote













    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:



    1. being able to implement (unary) operators with functions

    2. allowing said functions to have pass-by-reference arguments (so that they may mutate their arguments directly)

    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





    share|improve this answer


















    • 3




      The language will provide this: github.com/apple/swift-evolution/blob/master/proposals/…
      – Cristik
      Aug 24 at 6:09










    • Yes, but the question specifically asked for an operator, not a member function.
      – Lauri Piispanen
      Aug 24 at 6:34






    • 1




      "Neither does Rust" => Yes it does
      – Boiethios
      Aug 30 at 9:08










    • @Boiethios thanks! Edited for Rust - only allows overloaded operators for custom types, though, so no dice.
      – Lauri Piispanen
      Aug 30 at 12:46










    • @LauriPiispanen The rule is more general than that, and due to orphan rule, FYI
      – Boiethios
      Aug 30 at 12:53


















    up vote
    6
    down vote













    In Rust, you can create your own trait to extend the types that implement the Not trait:



    use std::ops::Not;
    use std::mem::replace;

    trait Flip
    fn flip(&mut self);


    impl<T> Flip for T
    where
    T: Not<Output = T> + Default,

    fn flip(&mut self)
    *self = replace(self, Default::default()).not();



    #[test]
    fn it_works()
    let mut b = true;
    b.flip();

    assert_eq!(b, false);



    You can also use ^= true as suggested, and in the case of Rust, there is no possible issue to do this because false is not a "disguised" integer like in C or C++:



    fn main() 
    let mut b = true;
    b ^= true;
    assert_eq!(b, false);

    let mut b = false;
    b ^= true;
    assert_eq!(b, true);






    share|improve this answer





























      up vote
      0
      down vote













      In Python



      Python supports such functionality, if the variable has bool type (which is True or False) with the exclusive or (^=) operator:



      a = False
      a ^= True
      print(a) # --> True
      a ^= True
      print(a) # --> False





      share|improve this answer



























        up vote
        -2
        down vote













        In C#:



        boolean.variable.down.here ^= true;


        The boolean ^ operator is XOR, and XORing with true is the same as inverting.






        share|improve this answer



























          up vote
          -3
          down vote













          In Fortran you can use:



          LOGICAL A = .TRUE.
          A = .NOT. A
          END





          share|improve this answer


















          • 1




            That isn’t a mutating operator.
            – Davis Herring
            Aug 22 at 1:00






          • 2




            A = .NOT. A? I know nothing about Fortran, but how is that any different than a = !a; in other languages? Which is exactly the expression the OP wanted to abbreviate...
            – AJPerez
            Aug 22 at 8:18










          Your Answer





          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "1"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f51927109%2fdoes-any-language-have-a-unary-boolean-toggle-operator%23new-answer', 'question_page');

          );

          Post as a guest






























          13 Answers
          13






          active

          oldest

          votes








          13 Answers
          13






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          121
          down vote













          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.






          share|improve this answer






















          • Comments are not for extended discussion; this conversation has been moved to chat.
            – Samuel Liew♦
            Aug 20 at 23:03














          up vote
          121
          down vote













          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.






          share|improve this answer






















          • Comments are not for extended discussion; this conversation has been moved to chat.
            – Samuel Liew♦
            Aug 20 at 23:03












          up vote
          121
          down vote










          up vote
          121
          down vote









          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.






          share|improve this answer














          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.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Aug 25 at 10:34









          André Pena

          26.4k28134181




          26.4k28134181










          answered Aug 20 at 8:52









          dfri

          33.2k44790




          33.2k44790











          • Comments are not for extended discussion; this conversation has been moved to chat.
            – Samuel Liew♦
            Aug 20 at 23:03
















          • Comments are not for extended discussion; this conversation has been moved to chat.
            – Samuel Liew♦
            Aug 20 at 23:03















          Comments are not for extended discussion; this conversation has been moved to chat.
          – Samuel Liew♦
          Aug 20 at 23:03




          Comments are not for extended discussion; this conversation has been moved to chat.
          – Samuel Liew♦
          Aug 20 at 23:03












          up vote
          30
          down vote













          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





          share|improve this answer
















          • 6




            “the Cardinal Sin of redefining the meaning of operators” — I get that you were exaggerating but it’s really not a cardinal sin to reassign new meanings to existing operators in general.
            – Konrad Rudolph
            Aug 20 at 10:05






          • 3




            @KonradRudolph What I mean by this of course that an operator should make logical sense with respect to its usual arithmetic or logical meaning. 'operator+` for 2 strings is logical, since concatenation is similar (in our mind's eye) to addition or accumulation. operator<< has come to mean 'streamed out' because of its original abuse in the STL. It will not naturally mean 'apply the transform function on the RHS', which is essentially what I have re-purposed it for here.
            – Richard Hodges
            Aug 20 at 10:11






          • 3




            I don’t think that’s a good argument, sorry. First off, string concatenation has completely different semantics from addition (it isn’t even commutative!). Secondly, by your logic << is a bit shift operator, not a “stream out” operator. The problem with your redefinition isn’t that it’s inconsistent with existing meanings of the operator, but rather that it adds no value over a simple function call.
            – Konrad Rudolph
            Aug 20 at 11:05






          • 6




            << seems like a bad overload. I'd do !invert= x; ;)
            – Yakk - Adam Nevraumont
            Aug 20 at 16:04






          • 10




            @Yakk-AdamNevraumont LOL, now you've got me started: godbolt.org/z/KIkesp
            – Richard Hodges
            Aug 20 at 17:17














          up vote
          30
          down vote













          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





          share|improve this answer
















          • 6




            “the Cardinal Sin of redefining the meaning of operators” — I get that you were exaggerating but it’s really not a cardinal sin to reassign new meanings to existing operators in general.
            – Konrad Rudolph
            Aug 20 at 10:05






          • 3




            @KonradRudolph What I mean by this of course that an operator should make logical sense with respect to its usual arithmetic or logical meaning. 'operator+` for 2 strings is logical, since concatenation is similar (in our mind's eye) to addition or accumulation. operator<< has come to mean 'streamed out' because of its original abuse in the STL. It will not naturally mean 'apply the transform function on the RHS', which is essentially what I have re-purposed it for here.
            – Richard Hodges
            Aug 20 at 10:11






          • 3




            I don’t think that’s a good argument, sorry. First off, string concatenation has completely different semantics from addition (it isn’t even commutative!). Secondly, by your logic << is a bit shift operator, not a “stream out” operator. The problem with your redefinition isn’t that it’s inconsistent with existing meanings of the operator, but rather that it adds no value over a simple function call.
            – Konrad Rudolph
            Aug 20 at 11:05






          • 6




            << seems like a bad overload. I'd do !invert= x; ;)
            – Yakk - Adam Nevraumont
            Aug 20 at 16:04






          • 10




            @Yakk-AdamNevraumont LOL, now you've got me started: godbolt.org/z/KIkesp
            – Richard Hodges
            Aug 20 at 17:17












          up vote
          30
          down vote










          up vote
          30
          down vote









          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





          share|improve this answer












          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






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Aug 20 at 10:03









          Richard Hodges

          53.6k55597




          53.6k55597







          • 6




            “the Cardinal Sin of redefining the meaning of operators” — I get that you were exaggerating but it’s really not a cardinal sin to reassign new meanings to existing operators in general.
            – Konrad Rudolph
            Aug 20 at 10:05






          • 3




            @KonradRudolph What I mean by this of course that an operator should make logical sense with respect to its usual arithmetic or logical meaning. 'operator+` for 2 strings is logical, since concatenation is similar (in our mind's eye) to addition or accumulation. operator<< has come to mean 'streamed out' because of its original abuse in the STL. It will not naturally mean 'apply the transform function on the RHS', which is essentially what I have re-purposed it for here.
            – Richard Hodges
            Aug 20 at 10:11






          • 3




            I don’t think that’s a good argument, sorry. First off, string concatenation has completely different semantics from addition (it isn’t even commutative!). Secondly, by your logic << is a bit shift operator, not a “stream out” operator. The problem with your redefinition isn’t that it’s inconsistent with existing meanings of the operator, but rather that it adds no value over a simple function call.
            – Konrad Rudolph
            Aug 20 at 11:05






          • 6




            << seems like a bad overload. I'd do !invert= x; ;)
            – Yakk - Adam Nevraumont
            Aug 20 at 16:04






          • 10




            @Yakk-AdamNevraumont LOL, now you've got me started: godbolt.org/z/KIkesp
            – Richard Hodges
            Aug 20 at 17:17












          • 6




            “the Cardinal Sin of redefining the meaning of operators” — I get that you were exaggerating but it’s really not a cardinal sin to reassign new meanings to existing operators in general.
            – Konrad Rudolph
            Aug 20 at 10:05






          • 3




            @KonradRudolph What I mean by this of course that an operator should make logical sense with respect to its usual arithmetic or logical meaning. 'operator+` for 2 strings is logical, since concatenation is similar (in our mind's eye) to addition or accumulation. operator<< has come to mean 'streamed out' because of its original abuse in the STL. It will not naturally mean 'apply the transform function on the RHS', which is essentially what I have re-purposed it for here.
            – Richard Hodges
            Aug 20 at 10:11






          • 3




            I don’t think that’s a good argument, sorry. First off, string concatenation has completely different semantics from addition (it isn’t even commutative!). Secondly, by your logic << is a bit shift operator, not a “stream out” operator. The problem with your redefinition isn’t that it’s inconsistent with existing meanings of the operator, but rather that it adds no value over a simple function call.
            – Konrad Rudolph
            Aug 20 at 11:05






          • 6




            << seems like a bad overload. I'd do !invert= x; ;)
            – Yakk - Adam Nevraumont
            Aug 20 at 16:04






          • 10




            @Yakk-AdamNevraumont LOL, now you've got me started: godbolt.org/z/KIkesp
            – Richard Hodges
            Aug 20 at 17:17







          6




          6




          “the Cardinal Sin of redefining the meaning of operators” — I get that you were exaggerating but it’s really not a cardinal sin to reassign new meanings to existing operators in general.
          – Konrad Rudolph
          Aug 20 at 10:05




          “the Cardinal Sin of redefining the meaning of operators” — I get that you were exaggerating but it’s really not a cardinal sin to reassign new meanings to existing operators in general.
          – Konrad Rudolph
          Aug 20 at 10:05




          3




          3




          @KonradRudolph What I mean by this of course that an operator should make logical sense with respect to its usual arithmetic or logical meaning. 'operator+` for 2 strings is logical, since concatenation is similar (in our mind's eye) to addition or accumulation. operator<< has come to mean 'streamed out' because of its original abuse in the STL. It will not naturally mean 'apply the transform function on the RHS', which is essentially what I have re-purposed it for here.
          – Richard Hodges
          Aug 20 at 10:11




          @KonradRudolph What I mean by this of course that an operator should make logical sense with respect to its usual arithmetic or logical meaning. 'operator+` for 2 strings is logical, since concatenation is similar (in our mind's eye) to addition or accumulation. operator<< has come to mean 'streamed out' because of its original abuse in the STL. It will not naturally mean 'apply the transform function on the RHS', which is essentially what I have re-purposed it for here.
          – Richard Hodges
          Aug 20 at 10:11




          3




          3




          I don’t think that’s a good argument, sorry. First off, string concatenation has completely different semantics from addition (it isn’t even commutative!). Secondly, by your logic << is a bit shift operator, not a “stream out” operator. The problem with your redefinition isn’t that it’s inconsistent with existing meanings of the operator, but rather that it adds no value over a simple function call.
          – Konrad Rudolph
          Aug 20 at 11:05




          I don’t think that’s a good argument, sorry. First off, string concatenation has completely different semantics from addition (it isn’t even commutative!). Secondly, by your logic << is a bit shift operator, not a “stream out” operator. The problem with your redefinition isn’t that it’s inconsistent with existing meanings of the operator, but rather that it adds no value over a simple function call.
          – Konrad Rudolph
          Aug 20 at 11:05




          6




          6




          << seems like a bad overload. I'd do !invert= x; ;)
          – Yakk - Adam Nevraumont
          Aug 20 at 16:04




          << seems like a bad overload. I'd do !invert= x; ;)
          – Yakk - Adam Nevraumont
          Aug 20 at 16:04




          10




          10




          @Yakk-AdamNevraumont LOL, now you've got me started: godbolt.org/z/KIkesp
          – Richard Hodges
          Aug 20 at 17:17




          @Yakk-AdamNevraumont LOL, now you've got me started: godbolt.org/z/KIkesp
          – Richard Hodges
          Aug 20 at 17:17










          up vote
          26
          down vote













          As long as we include assembly language...



          FORTH



          INVERT for a bitwise complement.



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






          share|improve this answer
















          • 1




            Arguable, in every stack-oriented language an unary not is a "toggle" operator :-)
            – Bergi
            Aug 21 at 16:28










          • Sure, it's a bit of a sideways answer as the OP is clearly thinking about C-like languages that have a traditional assignment statement. I think sideways answers like this have value, if only to show a part of the programming world that the reader might not have thought of. ("There are more programming languages in heaven and earth, Horatio, than are dreampt of in our philosophy.")
            – Wayne Conrad
            Aug 21 at 17:51















          up vote
          26
          down vote













          As long as we include assembly language...



          FORTH



          INVERT for a bitwise complement.



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






          share|improve this answer
















          • 1




            Arguable, in every stack-oriented language an unary not is a "toggle" operator :-)
            – Bergi
            Aug 21 at 16:28










          • Sure, it's a bit of a sideways answer as the OP is clearly thinking about C-like languages that have a traditional assignment statement. I think sideways answers like this have value, if only to show a part of the programming world that the reader might not have thought of. ("There are more programming languages in heaven and earth, Horatio, than are dreampt of in our philosophy.")
            – Wayne Conrad
            Aug 21 at 17:51













          up vote
          26
          down vote










          up vote
          26
          down vote









          As long as we include assembly language...



          FORTH



          INVERT for a bitwise complement.



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






          share|improve this answer












          As long as we include assembly language...



          FORTH



          INVERT for a bitwise complement.



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







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Aug 20 at 22:47









          Dr Sheldon

          36115




          36115







          • 1




            Arguable, in every stack-oriented language an unary not is a "toggle" operator :-)
            – Bergi
            Aug 21 at 16:28










          • Sure, it's a bit of a sideways answer as the OP is clearly thinking about C-like languages that have a traditional assignment statement. I think sideways answers like this have value, if only to show a part of the programming world that the reader might not have thought of. ("There are more programming languages in heaven and earth, Horatio, than are dreampt of in our philosophy.")
            – Wayne Conrad
            Aug 21 at 17:51













          • 1




            Arguable, in every stack-oriented language an unary not is a "toggle" operator :-)
            – Bergi
            Aug 21 at 16:28










          • Sure, it's a bit of a sideways answer as the OP is clearly thinking about C-like languages that have a traditional assignment statement. I think sideways answers like this have value, if only to show a part of the programming world that the reader might not have thought of. ("There are more programming languages in heaven and earth, Horatio, than are dreampt of in our philosophy.")
            – Wayne Conrad
            Aug 21 at 17:51








          1




          1




          Arguable, in every stack-oriented language an unary not is a "toggle" operator :-)
          – Bergi
          Aug 21 at 16:28




          Arguable, in every stack-oriented language an unary not is a "toggle" operator :-)
          – Bergi
          Aug 21 at 16:28












          Sure, it's a bit of a sideways answer as the OP is clearly thinking about C-like languages that have a traditional assignment statement. I think sideways answers like this have value, if only to show a part of the programming world that the reader might not have thought of. ("There are more programming languages in heaven and earth, Horatio, than are dreampt of in our philosophy.")
          – Wayne Conrad
          Aug 21 at 17:51





          Sure, it's a bit of a sideways answer as the OP is clearly thinking about C-like languages that have a traditional assignment statement. I think sideways answers like this have value, if only to show a part of the programming world that the reader might not have thought of. ("There are more programming languages in heaven and earth, Horatio, than are dreampt of in our philosophy.")
          – Wayne Conrad
          Aug 21 at 17:51











          up vote
          22
          down vote













          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].






          share|improve this answer




















          • C++ did the same thing with bool until C++17.
            – Davis Herring
            Aug 22 at 1:02














          up vote
          22
          down vote













          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].






          share|improve this answer




















          • C++ did the same thing with bool until C++17.
            – Davis Herring
            Aug 22 at 1:02












          up vote
          22
          down vote










          up vote
          22
          down vote









          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].






          share|improve this answer












          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].







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Aug 20 at 15:15









          supercat

          54.4k2111141




          54.4k2111141











          • C++ did the same thing with bool until C++17.
            – Davis Herring
            Aug 22 at 1:02
















          • C++ did the same thing with bool until C++17.
            – Davis Herring
            Aug 22 at 1:02















          C++ did the same thing with bool until C++17.
          – Davis Herring
          Aug 22 at 1:02




          C++ did the same thing with bool until C++17.
          – Davis Herring
          Aug 22 at 1:02










          up vote
          22
          down vote













          Assembly language



          NOT eax


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






          share|improve this answer




















          • I don't think this is quite what op had in mind, assuming this is x86 assembly. e.g. en.wikibooks.org/wiki/X86_Assembly/Logic ; here edx would be 0xFFFFFFFE because a bitwise NOT 0x00000001 = 0xFFFFFFFE
            – BurnsBA
            Aug 20 at 19:31







          • 5




            You can use all bits instead: NOT 0x00000000 = 0xFFFFFFFF
            – 4dr14n31t0r Th3 G4m3r
            Aug 20 at 19:33







          • 2




            Well, yes, though I was trying to the draw the distinction between boolean and bitwise operators. As op says in the question, assume the language has a well-defined boolean type: "(so no C-style int a = TRUE)."
            – BurnsBA
            Aug 21 at 12:22






          • 2




            @BurnsBA: indeed, assembly languages don't have a single set of well-defined truthy / falsy values. Over on code-golf, much has been discussed about which values you're allowed to return for boolean problems in various languages. Since asm doesn't have an if(x) construct, it's totally reasonable to allow 0 / -1 as false/true, like for SIMD compares (felixcloutier.com/x86/PCMPEQB:PCMPEQW:PCMPEQD.html). But you're right that this breaks if you use it on any other value.
            – Peter Cordes
            Aug 21 at 12:53






          • 1




            It's hard to have a single Boolean representation given that PCMPEQW results in 0/-1, but SETcc results in 0/+1.
            – Eugene Styer
            Aug 21 at 14:11














          up vote
          22
          down vote













          Assembly language



          NOT eax


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






          share|improve this answer




















          • I don't think this is quite what op had in mind, assuming this is x86 assembly. e.g. en.wikibooks.org/wiki/X86_Assembly/Logic ; here edx would be 0xFFFFFFFE because a bitwise NOT 0x00000001 = 0xFFFFFFFE
            – BurnsBA
            Aug 20 at 19:31







          • 5




            You can use all bits instead: NOT 0x00000000 = 0xFFFFFFFF
            – 4dr14n31t0r Th3 G4m3r
            Aug 20 at 19:33







          • 2




            Well, yes, though I was trying to the draw the distinction between boolean and bitwise operators. As op says in the question, assume the language has a well-defined boolean type: "(so no C-style int a = TRUE)."
            – BurnsBA
            Aug 21 at 12:22






          • 2




            @BurnsBA: indeed, assembly languages don't have a single set of well-defined truthy / falsy values. Over on code-golf, much has been discussed about which values you're allowed to return for boolean problems in various languages. Since asm doesn't have an if(x) construct, it's totally reasonable to allow 0 / -1 as false/true, like for SIMD compares (felixcloutier.com/x86/PCMPEQB:PCMPEQW:PCMPEQD.html). But you're right that this breaks if you use it on any other value.
            – Peter Cordes
            Aug 21 at 12:53






          • 1




            It's hard to have a single Boolean representation given that PCMPEQW results in 0/-1, but SETcc results in 0/+1.
            – Eugene Styer
            Aug 21 at 14:11












          up vote
          22
          down vote










          up vote
          22
          down vote









          Assembly language



          NOT eax


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






          share|improve this answer












          Assembly language



          NOT eax


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







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Aug 20 at 19:21









          4dr14n31t0r Th3 G4m3r

          40329




          40329











          • I don't think this is quite what op had in mind, assuming this is x86 assembly. e.g. en.wikibooks.org/wiki/X86_Assembly/Logic ; here edx would be 0xFFFFFFFE because a bitwise NOT 0x00000001 = 0xFFFFFFFE
            – BurnsBA
            Aug 20 at 19:31







          • 5




            You can use all bits instead: NOT 0x00000000 = 0xFFFFFFFF
            – 4dr14n31t0r Th3 G4m3r
            Aug 20 at 19:33







          • 2




            Well, yes, though I was trying to the draw the distinction between boolean and bitwise operators. As op says in the question, assume the language has a well-defined boolean type: "(so no C-style int a = TRUE)."
            – BurnsBA
            Aug 21 at 12:22






          • 2




            @BurnsBA: indeed, assembly languages don't have a single set of well-defined truthy / falsy values. Over on code-golf, much has been discussed about which values you're allowed to return for boolean problems in various languages. Since asm doesn't have an if(x) construct, it's totally reasonable to allow 0 / -1 as false/true, like for SIMD compares (felixcloutier.com/x86/PCMPEQB:PCMPEQW:PCMPEQD.html). But you're right that this breaks if you use it on any other value.
            – Peter Cordes
            Aug 21 at 12:53






          • 1




            It's hard to have a single Boolean representation given that PCMPEQW results in 0/-1, but SETcc results in 0/+1.
            – Eugene Styer
            Aug 21 at 14:11
















          • I don't think this is quite what op had in mind, assuming this is x86 assembly. e.g. en.wikibooks.org/wiki/X86_Assembly/Logic ; here edx would be 0xFFFFFFFE because a bitwise NOT 0x00000001 = 0xFFFFFFFE
            – BurnsBA
            Aug 20 at 19:31







          • 5




            You can use all bits instead: NOT 0x00000000 = 0xFFFFFFFF
            – 4dr14n31t0r Th3 G4m3r
            Aug 20 at 19:33







          • 2




            Well, yes, though I was trying to the draw the distinction between boolean and bitwise operators. As op says in the question, assume the language has a well-defined boolean type: "(so no C-style int a = TRUE)."
            – BurnsBA
            Aug 21 at 12:22






          • 2




            @BurnsBA: indeed, assembly languages don't have a single set of well-defined truthy / falsy values. Over on code-golf, much has been discussed about which values you're allowed to return for boolean problems in various languages. Since asm doesn't have an if(x) construct, it's totally reasonable to allow 0 / -1 as false/true, like for SIMD compares (felixcloutier.com/x86/PCMPEQB:PCMPEQW:PCMPEQD.html). But you're right that this breaks if you use it on any other value.
            – Peter Cordes
            Aug 21 at 12:53






          • 1




            It's hard to have a single Boolean representation given that PCMPEQW results in 0/-1, but SETcc results in 0/+1.
            – Eugene Styer
            Aug 21 at 14:11















          I don't think this is quite what op had in mind, assuming this is x86 assembly. e.g. en.wikibooks.org/wiki/X86_Assembly/Logic ; here edx would be 0xFFFFFFFE because a bitwise NOT 0x00000001 = 0xFFFFFFFE
          – BurnsBA
          Aug 20 at 19:31





          I don't think this is quite what op had in mind, assuming this is x86 assembly. e.g. en.wikibooks.org/wiki/X86_Assembly/Logic ; here edx would be 0xFFFFFFFE because a bitwise NOT 0x00000001 = 0xFFFFFFFE
          – BurnsBA
          Aug 20 at 19:31





          5




          5




          You can use all bits instead: NOT 0x00000000 = 0xFFFFFFFF
          – 4dr14n31t0r Th3 G4m3r
          Aug 20 at 19:33





          You can use all bits instead: NOT 0x00000000 = 0xFFFFFFFF
          – 4dr14n31t0r Th3 G4m3r
          Aug 20 at 19:33





          2




          2




          Well, yes, though I was trying to the draw the distinction between boolean and bitwise operators. As op says in the question, assume the language has a well-defined boolean type: "(so no C-style int a = TRUE)."
          – BurnsBA
          Aug 21 at 12:22




          Well, yes, though I was trying to the draw the distinction between boolean and bitwise operators. As op says in the question, assume the language has a well-defined boolean type: "(so no C-style int a = TRUE)."
          – BurnsBA
          Aug 21 at 12:22




          2




          2




          @BurnsBA: indeed, assembly languages don't have a single set of well-defined truthy / falsy values. Over on code-golf, much has been discussed about which values you're allowed to return for boolean problems in various languages. Since asm doesn't have an if(x) construct, it's totally reasonable to allow 0 / -1 as false/true, like for SIMD compares (felixcloutier.com/x86/PCMPEQB:PCMPEQW:PCMPEQD.html). But you're right that this breaks if you use it on any other value.
          – Peter Cordes
          Aug 21 at 12:53




          @BurnsBA: indeed, assembly languages don't have a single set of well-defined truthy / falsy values. Over on code-golf, much has been discussed about which values you're allowed to return for boolean problems in various languages. Since asm doesn't have an if(x) construct, it's totally reasonable to allow 0 / -1 as false/true, like for SIMD compares (felixcloutier.com/x86/PCMPEQB:PCMPEQW:PCMPEQD.html). But you're right that this breaks if you use it on any other value.
          – Peter Cordes
          Aug 21 at 12:53




          1




          1




          It's hard to have a single Boolean representation given that PCMPEQW results in 0/-1, but SETcc results in 0/+1.
          – Eugene Styer
          Aug 21 at 14:11




          It's hard to have a single Boolean representation given that PCMPEQW results in 0/-1, but SETcc results in 0/+1.
          – Eugene Styer
          Aug 21 at 14:11










          up vote
          19
          down vote













          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





          share|improve this answer






















          • Would you want to return b = !b as well? Someone reading foo = makenot(x) || y or just a simple foo = makenot(bar) might assume that makenot was a pure function, and assume there was no side-effect. Burying a side-effect inside a larger expression is probably bad style, and the only benefit of a non-void return type is enabling that.
            – Peter Cordes
            Aug 21 at 12:32










          • @MatteoItalia suggests template<typename T> T& invert(T& t) t = !t; return t; , which being templated will convert to/from bool if used on a non-bool object. IDK if that's good or bad. Presumably good.
            – Peter Cordes
            Aug 21 at 12:34














          up vote
          19
          down vote













          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





          share|improve this answer






















          • Would you want to return b = !b as well? Someone reading foo = makenot(x) || y or just a simple foo = makenot(bar) might assume that makenot was a pure function, and assume there was no side-effect. Burying a side-effect inside a larger expression is probably bad style, and the only benefit of a non-void return type is enabling that.
            – Peter Cordes
            Aug 21 at 12:32










          • @MatteoItalia suggests template<typename T> T& invert(T& t) t = !t; return t; , which being templated will convert to/from bool if used on a non-bool object. IDK if that's good or bad. Presumably good.
            – Peter Cordes
            Aug 21 at 12:34












          up vote
          19
          down vote










          up vote
          19
          down vote









          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





          share|improve this answer














          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






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Aug 20 at 9:12

























          answered Aug 20 at 8:50









          paxdiablo

          609k16512101639




          609k16512101639











          • Would you want to return b = !b as well? Someone reading foo = makenot(x) || y or just a simple foo = makenot(bar) might assume that makenot was a pure function, and assume there was no side-effect. Burying a side-effect inside a larger expression is probably bad style, and the only benefit of a non-void return type is enabling that.
            – Peter Cordes
            Aug 21 at 12:32










          • @MatteoItalia suggests template<typename T> T& invert(T& t) t = !t; return t; , which being templated will convert to/from bool if used on a non-bool object. IDK if that's good or bad. Presumably good.
            – Peter Cordes
            Aug 21 at 12:34
















          • Would you want to return b = !b as well? Someone reading foo = makenot(x) || y or just a simple foo = makenot(bar) might assume that makenot was a pure function, and assume there was no side-effect. Burying a side-effect inside a larger expression is probably bad style, and the only benefit of a non-void return type is enabling that.
            – Peter Cordes
            Aug 21 at 12:32










          • @MatteoItalia suggests template<typename T> T& invert(T& t) t = !t; return t; , which being templated will convert to/from bool if used on a non-bool object. IDK if that's good or bad. Presumably good.
            – Peter Cordes
            Aug 21 at 12:34















          Would you want to return b = !b as well? Someone reading foo = makenot(x) || y or just a simple foo = makenot(bar) might assume that makenot was a pure function, and assume there was no side-effect. Burying a side-effect inside a larger expression is probably bad style, and the only benefit of a non-void return type is enabling that.
          – Peter Cordes
          Aug 21 at 12:32




          Would you want to return b = !b as well? Someone reading foo = makenot(x) || y or just a simple foo = makenot(bar) might assume that makenot was a pure function, and assume there was no side-effect. Burying a side-effect inside a larger expression is probably bad style, and the only benefit of a non-void return type is enabling that.
          – Peter Cordes
          Aug 21 at 12:32












          @MatteoItalia suggests template<typename T> T& invert(T& t) t = !t; return t; , which being templated will convert to/from bool if used on a non-bool object. IDK if that's good or bad. Presumably good.
          – Peter Cordes
          Aug 21 at 12:34




          @MatteoItalia suggests template<typename T> T& invert(T& t) t = !t; return t; , which being templated will convert to/from bool if used on a non-bool object. IDK if that's good or bad. Presumably good.
          – Peter Cordes
          Aug 21 at 12:34










          up vote
          16
          down vote













          PostScript, being a concatenative, stack-oriented language like Forth, has a unary toggle, not. The not operator toggles the value on top of the stack. For example,



          true % push true onto the stack
          not % invert the top of stack
          % the top of stack is now false


          See the PostScript Language Reference Manual (pdf), p. 458.






          share|improve this answer


























            up vote
            16
            down vote













            PostScript, being a concatenative, stack-oriented language like Forth, has a unary toggle, not. The not operator toggles the value on top of the stack. For example,



            true % push true onto the stack
            not % invert the top of stack
            % the top of stack is now false


            See the PostScript Language Reference Manual (pdf), p. 458.






            share|improve this answer
























              up vote
              16
              down vote










              up vote
              16
              down vote









              PostScript, being a concatenative, stack-oriented language like Forth, has a unary toggle, not. The not operator toggles the value on top of the stack. For example,



              true % push true onto the stack
              not % invert the top of stack
              % the top of stack is now false


              See the PostScript Language Reference Manual (pdf), p. 458.






              share|improve this answer














              PostScript, being a concatenative, stack-oriented language like Forth, has a unary toggle, not. The not operator toggles the value on top of the stack. For example,



              true % push true onto the stack
              not % invert the top of stack
              % the top of stack is now false


              See the PostScript Language Reference Manual (pdf), p. 458.







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Aug 21 at 20:54

























              answered Aug 21 at 13:25









              Wayne Conrad

              69.4k18127162




              69.4k18127162




















                  up vote
                  13
                  down vote













                  Visual Basic.Net supports this via an extension method.



                  Define the extension method like so:



                  <Extension>
                  Public Sub Flip(ByRef someBool As Boolean)
                  someBool = Not someBool
                  End Sub


                  And then call it like this:



                  Dim someVariable As Boolean
                  someVariable = True
                  someVariable.Flip


                  So, your original example would look something like:



                  me.DataSource.TrackedObject.CurrentValue.BooleanFlag.Flip





                  share|improve this answer
















                  • 1




                    While this does function as the shorthand the author was seeking, of course, you must use two operators to implement Flip(): = and Not. It's interesting to learn that in the case of calling SomeInstance.SomeBoolean.Flip it works even if SomeBoolean is a property, whereas the equivalent C# code would not compile.
                    – BACON
                    Aug 21 at 5:53














                  up vote
                  13
                  down vote













                  Visual Basic.Net supports this via an extension method.



                  Define the extension method like so:



                  <Extension>
                  Public Sub Flip(ByRef someBool As Boolean)
                  someBool = Not someBool
                  End Sub


                  And then call it like this:



                  Dim someVariable As Boolean
                  someVariable = True
                  someVariable.Flip


                  So, your original example would look something like:



                  me.DataSource.TrackedObject.CurrentValue.BooleanFlag.Flip





                  share|improve this answer
















                  • 1




                    While this does function as the shorthand the author was seeking, of course, you must use two operators to implement Flip(): = and Not. It's interesting to learn that in the case of calling SomeInstance.SomeBoolean.Flip it works even if SomeBoolean is a property, whereas the equivalent C# code would not compile.
                    – BACON
                    Aug 21 at 5:53












                  up vote
                  13
                  down vote










                  up vote
                  13
                  down vote









                  Visual Basic.Net supports this via an extension method.



                  Define the extension method like so:



                  <Extension>
                  Public Sub Flip(ByRef someBool As Boolean)
                  someBool = Not someBool
                  End Sub


                  And then call it like this:



                  Dim someVariable As Boolean
                  someVariable = True
                  someVariable.Flip


                  So, your original example would look something like:



                  me.DataSource.TrackedObject.CurrentValue.BooleanFlag.Flip





                  share|improve this answer












                  Visual Basic.Net supports this via an extension method.



                  Define the extension method like so:



                  <Extension>
                  Public Sub Flip(ByRef someBool As Boolean)
                  someBool = Not someBool
                  End Sub


                  And then call it like this:



                  Dim someVariable As Boolean
                  someVariable = True
                  someVariable.Flip


                  So, your original example would look something like:



                  me.DataSource.TrackedObject.CurrentValue.BooleanFlag.Flip






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Aug 20 at 17:22









                  Reginald Blue

                  351310




                  351310







                  • 1




                    While this does function as the shorthand the author was seeking, of course, you must use two operators to implement Flip(): = and Not. It's interesting to learn that in the case of calling SomeInstance.SomeBoolean.Flip it works even if SomeBoolean is a property, whereas the equivalent C# code would not compile.
                    – BACON
                    Aug 21 at 5:53












                  • 1




                    While this does function as the shorthand the author was seeking, of course, you must use two operators to implement Flip(): = and Not. It's interesting to learn that in the case of calling SomeInstance.SomeBoolean.Flip it works even if SomeBoolean is a property, whereas the equivalent C# code would not compile.
                    – BACON
                    Aug 21 at 5:53







                  1




                  1




                  While this does function as the shorthand the author was seeking, of course, you must use two operators to implement Flip(): = and Not. It's interesting to learn that in the case of calling SomeInstance.SomeBoolean.Flip it works even if SomeBoolean is a property, whereas the equivalent C# code would not compile.
                  – BACON
                  Aug 21 at 5:53




                  While this does function as the shorthand the author was seeking, of course, you must use two operators to implement Flip(): = and Not. It's interesting to learn that in the case of calling SomeInstance.SomeBoolean.Flip it works even if SomeBoolean is a property, whereas the equivalent C# code would not compile.
                  – BACON
                  Aug 21 at 5:53










                  up vote
                  8
                  down vote













                  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:



                  1. being able to implement (unary) operators with functions

                  2. allowing said functions to have pass-by-reference arguments (so that they may mutate their arguments directly)

                  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





                  share|improve this answer


















                  • 3




                    The language will provide this: github.com/apple/swift-evolution/blob/master/proposals/…
                    – Cristik
                    Aug 24 at 6:09










                  • Yes, but the question specifically asked for an operator, not a member function.
                    – Lauri Piispanen
                    Aug 24 at 6:34






                  • 1




                    "Neither does Rust" => Yes it does
                    – Boiethios
                    Aug 30 at 9:08










                  • @Boiethios thanks! Edited for Rust - only allows overloaded operators for custom types, though, so no dice.
                    – Lauri Piispanen
                    Aug 30 at 12:46










                  • @LauriPiispanen The rule is more general than that, and due to orphan rule, FYI
                    – Boiethios
                    Aug 30 at 12:53















                  up vote
                  8
                  down vote













                  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:



                  1. being able to implement (unary) operators with functions

                  2. allowing said functions to have pass-by-reference arguments (so that they may mutate their arguments directly)

                  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





                  share|improve this answer


















                  • 3




                    The language will provide this: github.com/apple/swift-evolution/blob/master/proposals/…
                    – Cristik
                    Aug 24 at 6:09










                  • Yes, but the question specifically asked for an operator, not a member function.
                    – Lauri Piispanen
                    Aug 24 at 6:34






                  • 1




                    "Neither does Rust" => Yes it does
                    – Boiethios
                    Aug 30 at 9:08










                  • @Boiethios thanks! Edited for Rust - only allows overloaded operators for custom types, though, so no dice.
                    – Lauri Piispanen
                    Aug 30 at 12:46










                  • @LauriPiispanen The rule is more general than that, and due to orphan rule, FYI
                    – Boiethios
                    Aug 30 at 12:53













                  up vote
                  8
                  down vote










                  up vote
                  8
                  down vote









                  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:



                  1. being able to implement (unary) operators with functions

                  2. allowing said functions to have pass-by-reference arguments (so that they may mutate their arguments directly)

                  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





                  share|improve this answer














                  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:



                  1. being able to implement (unary) operators with functions

                  2. allowing said functions to have pass-by-reference arguments (so that they may mutate their arguments directly)

                  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






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Aug 30 at 12:45

























                  answered Aug 22 at 19:31









                  Lauri Piispanen

                  1,722916




                  1,722916







                  • 3




                    The language will provide this: github.com/apple/swift-evolution/blob/master/proposals/…
                    – Cristik
                    Aug 24 at 6:09










                  • Yes, but the question specifically asked for an operator, not a member function.
                    – Lauri Piispanen
                    Aug 24 at 6:34






                  • 1




                    "Neither does Rust" => Yes it does
                    – Boiethios
                    Aug 30 at 9:08










                  • @Boiethios thanks! Edited for Rust - only allows overloaded operators for custom types, though, so no dice.
                    – Lauri Piispanen
                    Aug 30 at 12:46










                  • @LauriPiispanen The rule is more general than that, and due to orphan rule, FYI
                    – Boiethios
                    Aug 30 at 12:53













                  • 3




                    The language will provide this: github.com/apple/swift-evolution/blob/master/proposals/…
                    – Cristik
                    Aug 24 at 6:09










                  • Yes, but the question specifically asked for an operator, not a member function.
                    – Lauri Piispanen
                    Aug 24 at 6:34






                  • 1




                    "Neither does Rust" => Yes it does
                    – Boiethios
                    Aug 30 at 9:08










                  • @Boiethios thanks! Edited for Rust - only allows overloaded operators for custom types, though, so no dice.
                    – Lauri Piispanen
                    Aug 30 at 12:46










                  • @LauriPiispanen The rule is more general than that, and due to orphan rule, FYI
                    – Boiethios
                    Aug 30 at 12:53








                  3




                  3




                  The language will provide this: github.com/apple/swift-evolution/blob/master/proposals/…
                  – Cristik
                  Aug 24 at 6:09




                  The language will provide this: github.com/apple/swift-evolution/blob/master/proposals/…
                  – Cristik
                  Aug 24 at 6:09












                  Yes, but the question specifically asked for an operator, not a member function.
                  – Lauri Piispanen
                  Aug 24 at 6:34




                  Yes, but the question specifically asked for an operator, not a member function.
                  – Lauri Piispanen
                  Aug 24 at 6:34




                  1




                  1




                  "Neither does Rust" => Yes it does
                  – Boiethios
                  Aug 30 at 9:08




                  "Neither does Rust" => Yes it does
                  – Boiethios
                  Aug 30 at 9:08












                  @Boiethios thanks! Edited for Rust - only allows overloaded operators for custom types, though, so no dice.
                  – Lauri Piispanen
                  Aug 30 at 12:46




                  @Boiethios thanks! Edited for Rust - only allows overloaded operators for custom types, though, so no dice.
                  – Lauri Piispanen
                  Aug 30 at 12:46












                  @LauriPiispanen The rule is more general than that, and due to orphan rule, FYI
                  – Boiethios
                  Aug 30 at 12:53





                  @LauriPiispanen The rule is more general than that, and due to orphan rule, FYI
                  – Boiethios
                  Aug 30 at 12:53











                  up vote
                  6
                  down vote













                  In Rust, you can create your own trait to extend the types that implement the Not trait:



                  use std::ops::Not;
                  use std::mem::replace;

                  trait Flip
                  fn flip(&mut self);


                  impl<T> Flip for T
                  where
                  T: Not<Output = T> + Default,

                  fn flip(&mut self)
                  *self = replace(self, Default::default()).not();



                  #[test]
                  fn it_works()
                  let mut b = true;
                  b.flip();

                  assert_eq!(b, false);



                  You can also use ^= true as suggested, and in the case of Rust, there is no possible issue to do this because false is not a "disguised" integer like in C or C++:



                  fn main() 
                  let mut b = true;
                  b ^= true;
                  assert_eq!(b, false);

                  let mut b = false;
                  b ^= true;
                  assert_eq!(b, true);






                  share|improve this answer


























                    up vote
                    6
                    down vote













                    In Rust, you can create your own trait to extend the types that implement the Not trait:



                    use std::ops::Not;
                    use std::mem::replace;

                    trait Flip
                    fn flip(&mut self);


                    impl<T> Flip for T
                    where
                    T: Not<Output = T> + Default,

                    fn flip(&mut self)
                    *self = replace(self, Default::default()).not();



                    #[test]
                    fn it_works()
                    let mut b = true;
                    b.flip();

                    assert_eq!(b, false);



                    You can also use ^= true as suggested, and in the case of Rust, there is no possible issue to do this because false is not a "disguised" integer like in C or C++:



                    fn main() 
                    let mut b = true;
                    b ^= true;
                    assert_eq!(b, false);

                    let mut b = false;
                    b ^= true;
                    assert_eq!(b, true);






                    share|improve this answer
























                      up vote
                      6
                      down vote










                      up vote
                      6
                      down vote









                      In Rust, you can create your own trait to extend the types that implement the Not trait:



                      use std::ops::Not;
                      use std::mem::replace;

                      trait Flip
                      fn flip(&mut self);


                      impl<T> Flip for T
                      where
                      T: Not<Output = T> + Default,

                      fn flip(&mut self)
                      *self = replace(self, Default::default()).not();



                      #[test]
                      fn it_works()
                      let mut b = true;
                      b.flip();

                      assert_eq!(b, false);



                      You can also use ^= true as suggested, and in the case of Rust, there is no possible issue to do this because false is not a "disguised" integer like in C or C++:



                      fn main() 
                      let mut b = true;
                      b ^= true;
                      assert_eq!(b, false);

                      let mut b = false;
                      b ^= true;
                      assert_eq!(b, true);






                      share|improve this answer














                      In Rust, you can create your own trait to extend the types that implement the Not trait:



                      use std::ops::Not;
                      use std::mem::replace;

                      trait Flip
                      fn flip(&mut self);


                      impl<T> Flip for T
                      where
                      T: Not<Output = T> + Default,

                      fn flip(&mut self)
                      *self = replace(self, Default::default()).not();



                      #[test]
                      fn it_works()
                      let mut b = true;
                      b.flip();

                      assert_eq!(b, false);



                      You can also use ^= true as suggested, and in the case of Rust, there is no possible issue to do this because false is not a "disguised" integer like in C or C++:



                      fn main() 
                      let mut b = true;
                      b ^= true;
                      assert_eq!(b, false);

                      let mut b = false;
                      b ^= true;
                      assert_eq!(b, true);







                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited 2 days ago

























                      answered Aug 27 at 12:48









                      Boiethios

                      8,53522762




                      8,53522762




















                          up vote
                          0
                          down vote













                          In Python



                          Python supports such functionality, if the variable has bool type (which is True or False) with the exclusive or (^=) operator:



                          a = False
                          a ^= True
                          print(a) # --> True
                          a ^= True
                          print(a) # --> False





                          share|improve this answer
























                            up vote
                            0
                            down vote













                            In Python



                            Python supports such functionality, if the variable has bool type (which is True or False) with the exclusive or (^=) operator:



                            a = False
                            a ^= True
                            print(a) # --> True
                            a ^= True
                            print(a) # --> False





                            share|improve this answer






















                              up vote
                              0
                              down vote










                              up vote
                              0
                              down vote









                              In Python



                              Python supports such functionality, if the variable has bool type (which is True or False) with the exclusive or (^=) operator:



                              a = False
                              a ^= True
                              print(a) # --> True
                              a ^= True
                              print(a) # --> False





                              share|improve this answer












                              In Python



                              Python supports such functionality, if the variable has bool type (which is True or False) with the exclusive or (^=) operator:



                              a = False
                              a ^= True
                              print(a) # --> True
                              a ^= True
                              print(a) # --> False






                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered 2 days ago









                              Andriy Ivaneyko

                              10.2k22339




                              10.2k22339




















                                  up vote
                                  -2
                                  down vote













                                  In C#:



                                  boolean.variable.down.here ^= true;


                                  The boolean ^ operator is XOR, and XORing with true is the same as inverting.






                                  share|improve this answer
























                                    up vote
                                    -2
                                    down vote













                                    In C#:



                                    boolean.variable.down.here ^= true;


                                    The boolean ^ operator is XOR, and XORing with true is the same as inverting.






                                    share|improve this answer






















                                      up vote
                                      -2
                                      down vote










                                      up vote
                                      -2
                                      down vote









                                      In C#:



                                      boolean.variable.down.here ^= true;


                                      The boolean ^ operator is XOR, and XORing with true is the same as inverting.






                                      share|improve this answer












                                      In C#:



                                      boolean.variable.down.here ^= true;


                                      The boolean ^ operator is XOR, and XORing with true is the same as inverting.







                                      share|improve this answer












                                      share|improve this answer



                                      share|improve this answer










                                      answered Aug 24 at 6:42









                                      rakensi

                                      1,13811318




                                      1,13811318




















                                          up vote
                                          -3
                                          down vote













                                          In Fortran you can use:



                                          LOGICAL A = .TRUE.
                                          A = .NOT. A
                                          END





                                          share|improve this answer


















                                          • 1




                                            That isn’t a mutating operator.
                                            – Davis Herring
                                            Aug 22 at 1:00






                                          • 2




                                            A = .NOT. A? I know nothing about Fortran, but how is that any different than a = !a; in other languages? Which is exactly the expression the OP wanted to abbreviate...
                                            – AJPerez
                                            Aug 22 at 8:18














                                          up vote
                                          -3
                                          down vote













                                          In Fortran you can use:



                                          LOGICAL A = .TRUE.
                                          A = .NOT. A
                                          END





                                          share|improve this answer


















                                          • 1




                                            That isn’t a mutating operator.
                                            – Davis Herring
                                            Aug 22 at 1:00






                                          • 2




                                            A = .NOT. A? I know nothing about Fortran, but how is that any different than a = !a; in other languages? Which is exactly the expression the OP wanted to abbreviate...
                                            – AJPerez
                                            Aug 22 at 8:18












                                          up vote
                                          -3
                                          down vote










                                          up vote
                                          -3
                                          down vote









                                          In Fortran you can use:



                                          LOGICAL A = .TRUE.
                                          A = .NOT. A
                                          END





                                          share|improve this answer














                                          In Fortran you can use:



                                          LOGICAL A = .TRUE.
                                          A = .NOT. A
                                          END






                                          share|improve this answer














                                          share|improve this answer



                                          share|improve this answer








                                          edited Aug 22 at 0:38









                                          Grant Miller

                                          2,98971938




                                          2,98971938










                                          answered Aug 21 at 23:32









                                          Fred Mitchell

                                          1,5781022




                                          1,5781022







                                          • 1




                                            That isn’t a mutating operator.
                                            – Davis Herring
                                            Aug 22 at 1:00






                                          • 2




                                            A = .NOT. A? I know nothing about Fortran, but how is that any different than a = !a; in other languages? Which is exactly the expression the OP wanted to abbreviate...
                                            – AJPerez
                                            Aug 22 at 8:18












                                          • 1




                                            That isn’t a mutating operator.
                                            – Davis Herring
                                            Aug 22 at 1:00






                                          • 2




                                            A = .NOT. A? I know nothing about Fortran, but how is that any different than a = !a; in other languages? Which is exactly the expression the OP wanted to abbreviate...
                                            – AJPerez
                                            Aug 22 at 8:18







                                          1




                                          1




                                          That isn’t a mutating operator.
                                          – Davis Herring
                                          Aug 22 at 1:00




                                          That isn’t a mutating operator.
                                          – Davis Herring
                                          Aug 22 at 1:00




                                          2




                                          2




                                          A = .NOT. A? I know nothing about Fortran, but how is that any different than a = !a; in other languages? Which is exactly the expression the OP wanted to abbreviate...
                                          – AJPerez
                                          Aug 22 at 8:18




                                          A = .NOT. A? I know nothing about Fortran, but how is that any different than a = !a; in other languages? Which is exactly the expression the OP wanted to abbreviate...
                                          – AJPerez
                                          Aug 22 at 8:18

















                                           

                                          draft saved


                                          draft discarded















































                                           


                                          draft saved


                                          draft discarded














                                          StackExchange.ready(
                                          function ()
                                          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f51927109%2fdoes-any-language-have-a-unary-boolean-toggle-operator%23new-answer', 'question_page');

                                          );

                                          Post as a guest













































































                                          Comments

                                          Popular posts from this blog

                                          What does second last employer means? [closed]

                                          List of Gilmore Girls characters

                                          Confectionery