# A Plea for Bit-Twiddlers! (please keep ! as logical negation, separate from bitwise negation!)

**URL:** <https://discourse.julialang.org/t/a-plea-for-bit-twiddlers-please-keep-as-logical-negation-separate-from-bitwise-negation/8297>\
**Category:** Internals & Design\
**Created:** [January 11, 2018, 9:56pm UTC](https://discourse.julialang.org/t/a-plea-for-bit-twiddlers-please-keep-as-logical-negation-separate-from-bitwise-negation/8297 "2018-01-11T21:56:49Z")\
**Posts on this page:** 20\
**Page:** 2

<div class="post-metadata">

**Author:** ![ScottPJones](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scottpjones/32/146_2.png) [@ScottPJones](https://discourse.julialang.org/u/ScottPJones)\
**Post date:** [January 12, 2018, 1:12pm UTC](https://discourse.julialang.org/t/a-plea-for-bit-twiddlers-please-keep-as-logical-negation-separate-from-bitwise-negation/8297/21 "2018-01-12T13:12:22Z")

</div>

The fact that `&` and `|` operate on `Bool` is actually an argument in favor of also allowing `!` to operate (as a _logical_ operator, not bitwise) on `Integer` types (converting non-zero to `false`, and zero to `true`).  
If Julia supported primitive types that were not a multiple of 8 bits (something like that which would be great for dealing with fields in C/C++/etc. structs), then `Bool` could be implemented as `primitive type Bool 1 end` instead of making it a `UInt8` under the hood.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 12, 2018, 1:22pm UTC](https://discourse.julialang.org/t/a-plea-for-bit-twiddlers-please-keep-as-logical-negation-separate-from-bitwise-negation/8297/22 "2018-01-12T13:22:09Z")

</div>

> [@ScottPJones](#):
>
> an argument in favor of also allowing ! to operate (as a logical operator, not bitwise) on Integer types (converting non-zero to false, and zero to true).

I disagree, I think that allowing non-booleans in contexts one expects booleans makes it easy for bugs to slip though. This was an unfortunate choice in C, but also in the Lisp family (anything not `nil` is true), and many other languages that follow that pattern. Julia chose to have a `Bool` type, instead of repurposing some other type or allowing anything to be interpreted as a boolean with a bit of imagination.

I also rather like the `!!x == x` invariance, which `!` operating on `Int`s in the manner you suggest would break.

---

<div class="post-metadata">

**Author:** ![ScottPJones](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scottpjones/32/146_2.png) [@ScottPJones](https://discourse.julialang.org/u/ScottPJones)\
**Post date:** [January 12, 2018, 1:29pm UTC](https://discourse.julialang.org/t/a-plea-for-bit-twiddlers-please-keep-as-logical-negation-separate-from-bitwise-negation/8297/23 "2018-01-12T13:29:11Z")

</div>

> [@Tamas\_Papp](#):
>
> I also rather like the !!x == x invariance, which ! operating on Ints in the manner you suggest would break.

Where is that an invariance? I’ve never seen that described as a property of `!` in any language before.  
Using `!!var` is an old C idiom, to convert an integer in var to 0 or 1, instead of `(var != 0)`, 2 characters vs. 7.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 12, 2018, 1:42pm UTC](https://discourse.julialang.org/t/a-plea-for-bit-twiddlers-please-keep-as-logical-negation-separate-from-bitwise-negation/8297/24 "2018-01-12T13:42:10Z")

</div>

> [@ScottPJones](#):
>
> Where is that an invariance?

In Julia (at least that is my impression), now for `~` and `!` separately (unless I missed some case), but after the merge for `!`. I find this rather neat.

> [@ScottPJones](#):
>
> Using `!!var` is an old C idiom

And a quite horrible one IMO. One of those 1000+ C idioms where a string of characters does what you want, but for some reason people refrain from naming it for that purpose. If you know the idiom, you can reverse engineer intent, otherwise not. Truly an _idiom_ in the [sense](http://wordnetweb.princeton.edu/perl/webwn?s=idiom&sub=Search+WordNet&o2=&o0=1&o8=1&o1=1&o7=&o5=&o9=&o6=&o3=&o4=&h=) of

> an expression whose meanings cannot be inferred from the meanings of the words that make it up

Some people consider such idioms bad style.

---

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [January 12, 2018, 1:50pm UTC](https://discourse.julialang.org/t/a-plea-for-bit-twiddlers-please-keep-as-logical-negation-separate-from-bitwise-negation/8297/25 "2018-01-12T13:50:12Z")

</div>

> [@Tamas\_Papp](#):
>
> I disagree, I think that allowing non-booleans in contexts one expects booleans makes it easy for bugs to slip though. This was an unfortunate choice in C,

Excuse me to put it this way but I disagree on your disagreement.

---

<div class="post-metadata">

**Author:** ![ScottPJones](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scottpjones/32/146_2.png) [@ScottPJones](https://discourse.julialang.org/u/ScottPJones)\
**Post date:** [January 12, 2018, 3:02pm UTC](https://discourse.julialang.org/t/a-plea-for-bit-twiddlers-please-keep-as-logical-negation-separate-from-bitwise-negation/8297/26 "2018-01-12T15:02:06Z")

</div>

> [@Tamas\_Papp](#):
>
> an expression whose meanings cannot be inferred from the meanings of the words that make it up

It’s not an idiom in that sense at all. Any C/C++/… programmer knows that ! will convert 0/non-zero to 1/0 (true/false), and that doing that twice would give you 0/1.

Changing this in Julia I think is the sort of thing that can lead to bugs, when pretty much every other common language (except Rust) has `!` and `~` with separate meanings for logical and bitwise.

This is the same as the problem of false cognates when learning a foreign language, for example when somebody tries to say “embarrassed” in Spanish, and comes up with “pregnant” (embarazada).

If people are so dead set on the desire to free up `~`, then at least don’t conflate bitwise and logical for `!`, and change `~` to `¬` instead (and possibly free up `&` and `|`, and move those to `∧` and `∨`, so the bitwise operators are consistently Unicode operators in Julia.).  
At least then, people reading bit-twiddling code in Julia would probably recognize the meanings of those Unicode operators, or at least know to look them up, instead of seeing `!` and believing it is doing something that it does not.

---

<div class="post-metadata">

**Author:** ![jeff.bezanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff.bezanson/32/48_2.png) [@jeff.bezanson](https://discourse.julialang.org/u/jeff.bezanson)\
**Post date:** [January 12, 2018, 4:29pm UTC](https://discourse.julialang.org/t/a-plea-for-bit-twiddlers-please-keep-as-logical-negation-separate-from-bitwise-negation/8297/27 "2018-01-12T16:29:18Z")

</div>

> [@ScottPJones](#):
>
> Yet the math guys wanted to save a single \* in 2\*n, and just be able to write 2n.

Right, only math guys ever multiply numbers by 2. Most programmers would never do anything like that, ever.

---

<div class="post-metadata">

**Author:** ![ScottPJones](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scottpjones/32/146_2.png) [@ScottPJones](https://discourse.julialang.org/u/ScottPJones)\
**Post date:** [January 12, 2018, 5:09pm UTC](https://discourse.julialang.org/t/a-plea-for-bit-twiddlers-please-keep-as-logical-negation-separate-from-bitwise-negation/8297/28 "2018-01-12T17:09:22Z")

</div>

I think most programmers don’t mind the extra character - and would rather not worry about all the strange cases that using juxtaposition as syntax causes.  
TBH, for mathematicians in Julia, the justification though doesn’t seem to be saving one character, but rather, make stuff look like math.

I should be clear, I’m not trying to say that’s necessarily a _bad_ thing, it’s just something that needs to be thought about a lot in advance, all the pros and cons of something like using juxtaposition, or changing an operator that has pretty much the same meaning on all major languages, just to free up one, for ?.

Julians are lucky in that they can use any number of Unicode operators for anything new, without making code confusable by being almost, but not quite, the same as most of the other languages.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [January 12, 2018, 5:20pm UTC](https://discourse.julialang.org/t/a-plea-for-bit-twiddlers-please-keep-as-logical-negation-separate-from-bitwise-negation/8297/29 "2018-01-12T17:20:12Z")

</div>

> [@ScottPJones](#):
>
> think most programmers don’t mind the extra character

I love the juxtaposition syntax, even though it’s to a large degree about aesthetics. It’s not just one character, though. It’s all those cases where I can change

```julia
a/(2 * n)

```

into

```julia
a/2n

```

---

<div class="post-metadata">

**Author:** ![ScottPJones](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scottpjones/32/146_2.png) [@ScottPJones](https://discourse.julialang.org/u/ScottPJones)\
**Post date:** [January 12, 2018, 5:26pm UTC](https://discourse.julialang.org/t/a-plea-for-bit-twiddlers-please-keep-as-logical-negation-separate-from-bitwise-negation/8297/30 "2018-01-12T17:26:09Z")

</div>

Yes, like I said, I wasn’t trying to say it’s a bad thing, and probably the right choice for a language with a focus on being able to do math well, but for people that don’t have a lot of `*`s in their code anyway (I have almost none), having the code look like math or saving a few characters in that case is not a big deal, while some of the weird edge cases in the syntax cause more problems.

For bit twiddlers used to C, being able to test for 0 vs. non-zero with a simple `!` feels the same, the code feels rather clumsy and inelegant without it.  
(Nicely enough with Julia 🙂 , as I said before, a one-line bit of piracy means my code still looks nice and succinct to me, by making `!` work on `Integer`, where otherwise it would just have been a `MethodError`)

---

<div class="post-metadata">

**Author:** ![jeff.bezanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff.bezanson/32/48_2.png) [@jeff.bezanson](https://discourse.julialang.org/u/jeff.bezanson)\
**Post date:** [January 12, 2018, 9:08pm UTC](https://discourse.julialang.org/t/a-plea-for-bit-twiddlers-please-keep-as-logical-negation-separate-from-bitwise-negation/8297/31 "2018-01-12T21:08:12Z")

</div>

A good way to do this is to define

```julia
!x = Base.:!(x)
!(x::Integer) = (x == 0)

```

in your code. Then there’s not even any piracy.

---

<div class="post-metadata">

**Author:** ![ScottPJones](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scottpjones/32/146_2.png) [@ScottPJones](https://discourse.julialang.org/u/ScottPJones)\
**Post date:** [January 12, 2018, 9:38pm UTC](https://discourse.julialang.org/t/a-plea-for-bit-twiddlers-please-keep-as-logical-negation-separate-from-bitwise-negation/8297/32 "2018-01-12T21:38:49Z")

</div>

I guess I’m missing something, how is that definition different from:

> [@ScottPJones](#):
>
> Base.:!(val::Integer) = iszero(val)

(waiting to learn from the Jedi (oops) Julia Master!)

Edit: maybe I get it now, it’s overwriting `!` in my package, not extending it, right?

---

<div class="post-metadata">

**Author:** ![yurivish](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yurivish/32/307_2.png) [@yurivish](https://discourse.julialang.org/u/yurivish)\
**Post date:** [January 12, 2018, 9:41pm UTC](https://discourse.julialang.org/t/a-plea-for-bit-twiddlers-please-keep-as-logical-negation-separate-from-bitwise-negation/8297/33 "2018-01-12T21:41:15Z")

</div>

Yes, it’s creating a new `!` inside your module that defaults to `Base.!` behavior for everything but `Integer`s. This way everybody else who uses `!` will continue to get the standard behavior (unless they import `!` from your module).

---

<div class="post-metadata">

**Author:** ![ScottPJones](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scottpjones/32/146_2.png) [@ScottPJones](https://discourse.julialang.org/u/ScottPJones)\
**Post date:** [January 12, 2018, 10:20pm UTC](https://discourse.julialang.org/t/a-plea-for-bit-twiddlers-please-keep-as-logical-negation-separate-from-bitwise-negation/8297/34 "2018-01-12T22:20:07Z")

</div>

The one difficulty is I’d like to make that definition easily available by just using a module, and I don’t see how to do that without extending Base.:!

---

<div class="post-metadata">

**Author:** ![yurivish](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yurivish/32/307_2.png) [@yurivish](https://discourse.julialang.org/u/yurivish)\
**Post date:** [January 12, 2018, 10:22pm UTC](https://discourse.julialang.org/t/a-plea-for-bit-twiddlers-please-keep-as-logical-negation-separate-from-bitwise-negation/8297/35 "2018-01-12T22:22:49Z")

</div>

You would have to say `using Foo: !`.

---

<div class="post-metadata">

**Author:** ![ScottPJones](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scottpjones/32/146_2.png) [@ScottPJones](https://discourse.julialang.org/u/ScottPJones)\
**Post date:** [January 12, 2018, 10:26pm UTC](https://discourse.julialang.org/t/a-plea-for-bit-twiddlers-please-keep-as-logical-negation-separate-from-bitwise-negation/8297/36 "2018-01-12T22:26:30Z")

</div>

I thought that would give a conflict (you know, use must use Base.xxx and Foo.xxx)

---

<div class="post-metadata">

**Author:** ![ScottPJones](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scottpjones/32/146_2.png) [@ScottPJones](https://discourse.julialang.org/u/ScottPJones)\
**Post date:** [January 12, 2018, 10:28pm UTC](https://discourse.julialang.org/t/a-plea-for-bit-twiddlers-please-keep-as-logical-negation-separate-from-bitwise-negation/8297/37 "2018-01-12T22:28:21Z")

</div>

Folks - let me know what you feel about my proposal, consolidated from other’s ideas here and on GitHub, and join in the Tomatina (a festival in Spain of throwing tomatos) 😀.

> [@A Modest Proposal (for !, &, | and ~)](https://discourse.julialang.org/t/a-modest-proposal-for-and/8330):
>
> Here is my combination of a lot of other people’s ideas and a few of my own into what I believe is a rather consistent proposal, that would meet everybody’s needs and desires (at least, so far as not go much against other people’s). First off, I think that the one real invariant I’ve seen for the use of ! in computer languages, is that the result is a boolean (or whatever the accepted values for true/false are, i.e. t and (), or 1 and 0, or true and false, etc.). I guess that’s why making ! t…

---

<div class="post-metadata">

**Author:** ![ggggggggg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ggggggggg/32/265_2.png) [@ggggggggg](https://discourse.julialang.org/u/ggggggggg)\
**Post date:** [January 12, 2018, 10:51pm UTC](https://discourse.julialang.org/t/a-plea-for-bit-twiddlers-please-keep-as-logical-negation-separate-from-bitwise-negation/8297/38 "2018-01-12T22:51:31Z")

</div>

`!(val::Integer) = (val == 0)` Please don’t do this. I love that values non-booleans don’t have magic comparison properties like in Python, it’s just too many special cases to remember. Also it would be weird if `if !a end` worked for a variable where `if a end` errors.

---

<div class="post-metadata">

**Author:** ![ggggggggg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ggggggggg/32/265_2.png) [@ggggggggg](https://discourse.julialang.org/u/ggggggggg)\
**Post date:** [January 12, 2018, 11:23pm UTC](https://discourse.julialang.org/t/a-plea-for-bit-twiddlers-please-keep-as-logical-negation-separate-from-bitwise-negation/8297/39 "2018-01-12T23:23:44Z")

</div>

If `!` is used for both logical and bitwise not, couldn’t `foo &= ~0x00ff` become `foo &= !0x00ff` which is equally concise?

---

<div class="post-metadata">

**Author:** ![ScottPJones](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scottpjones/32/146_2.png) [@ScottPJones](https://discourse.julialang.org/u/ScottPJones)\
**Post date:** [January 13, 2018, 1:54am UTC](https://discourse.julialang.org/t/a-plea-for-bit-twiddlers-please-keep-as-logical-negation-separate-from-bitwise-negation/8297/40 "2018-01-13T01:54:41Z")

</div>

> [@ggggggggg](#):
>
> it’s just too many special cases to remember. Also it would be weird if if !a end worked for a variable where if a end errors.

Special cases? I actually think of it as being a very generic rule, no special cases at all. `!` returns a boolean based on the type of the value. That seems very Julian to me. Just like the relational operators can be used with many different types of values, but they always return a boolean value.  
Just as `if iszero(a) ...` works, even if `if a` doesn’t, so should `if !a` work.

> [@ggggggggg](#):
>
> If ! is used for both logical and bitwise not, couldn’t foo &= ~0x00ff become foo &= !0x00ff which is equally concise?

The problem there is that anybody used to most of the languages in the world expect that `!` returns a boolean value, and never anything else (just the Rust people don’t, that I’m aware of so far)

I think that `foo ∧= ¬0x00ff` would be more likely to be understood, people aren’t used to using those Unicode operators, but they may very well know that they are boolean operations. `foo and= not(0x00ff)` is also less likely to confuse people coming from the many C-like languages.  
(there are many languages that in other aspects are not at all like C, but that follow C’s conventions for logical and bitwise operators, like PHP, Perl, Ruby, or some or most of them, like Python or Rust).

[Previous page](https://discourse.julialang.org/t/a-plea-for-bit-twiddlers-please-keep-as-logical-negation-separate-from-bitwise-negation/8297.md?page=1)

[Next page](https://discourse.julialang.org/t/a-plea-for-bit-twiddlers-please-keep-as-logical-negation-separate-from-bitwise-negation/8297.md?page=3)
