Zig: "Not" instead of "!"

Created on 9 Oct 2020  Â·  10Comments  Â·  Source: ziglang/zig

Should we use a not operator instead of unary ! for logical NOT?

This would be consistent with the spelling of and and or logical operators. It's also how Eiffel and Python do it (as well as Perl and Pascal).

It would also make the meaning of ! more focused in Zig, to be used for error unions.

(That'd leave just the distinct != operator related to negation, again just like Python. I won't suggest using the SQL style <> instead 😄 ).

breaking proposal

Most helpful comment

and and or are keywords because they are used for control flow. (a and do_something() will only call do_something if a is true.) ! does not do any control flow, so it is consistent with other operators like &, |, >>, <<, %, ++, **…

(also I'm biased against this because not usually doesn't look very good imo)

All 10 comments

and and or are keywords because they are used for control flow. (a and do_something() will only call do_something if a is true.) ! does not do any control flow, so it is consistent with other operators like &, |, >>, <<, %, ++, **…

(also I'm biased against this because not usually doesn't look very good imo)

Since bool negation is quasi-control flow it can be either way, i think the problem with ! is that its bad for readability.

Just as personal preference, reading && is a little more confusing than and, but reading ! gives a clear meaning in my opinion.
while(!a == (24 < 25)) feels a lot better to read than while(not a == (24 < 25))

I honestly don't know why I care about this, but status-quo feels a lot clearer to me; probably having worked with Lua with its special condition evaluations.

Examples with booleans and boolean vectors: let a: bool, b: bool, av: std.meta.Vector(8, bool) and bv: std.meta.Vector(8, bool).

  • a & b makes sense: it's a binary boolean operation.
  • av & bv also has clear element-wise semantics, resulting in a new vector.
  • a and b can make sense, it's a special case of the short-circuit operation where the control flow difference doesn't matter.
  • av and bv has no clear semantics, and is not allowed by the language.

In status-quo, !a is a unary boolean operation, and !av has clear element-wise semantics.
Changing this to not a would also lead to writing the negated boolean vector as not av. Having a keyword for the element-wise operation looks awkward to me.

But I guess it's ultimately purely a question of style (-> whether your habit/background comes from C or Python). The proposal does lead away from the current rule-of-thumb: control-flow-via-keywords.

not a == b melts my brain. I think Python it's actually equivalent to not (a == b), which is jarring coming from a C background. I think using a punctuation character is better for readability (assuming C precedence rules), since ! visually hugs the term it's prefixing, so it LOOKS like it has higher precedence, which it does. No ambiguity.

I would have less of a problem with not if https://github.com/ziglang/zig/issues/114 were implemented.

I think there's definitely a matter of preference here, but for me it comes down to how tightly the operator binds. Looking at the precedence table for Zig:

// Higher Precedence
x() x[] x.y
a!b
!x -x -%x ~x &x ?x
x{} x.* x.?
! * / % ** *% ||
+ - ++ +% -%
<< >>
& ^ |
== != < > <= >=
and
or
orelse catch
= *= /= %= += -= <<= >>= &= ^= |=
// Lower Precedence

You can see that the unary not is in the same block as the other unary operators. Which means that in the example not x == y, the not binds to x, not x == y. This is clear in the current expression !x == y because it's unusual to put a space between unary not and its operand. But if the operator is the word not, it requires that there is always a space (or a symbol, e.g. parentheses) between the operator and its operand.

There might be an argument that the unary not should also be moved to be closer to and/or in the precedence order. Python actually does this, which is part of the reason I find it difficult to reason about boolean expressions that use not in python. But I think that's more from inexperience than anything else. I think changing both the operator and the precedence order is more appealing, though I'm on the fence about whether it's something we should actually do.

114 is still planned for anything but trivially obvious operator precedence

Was this intended to be closed?

Though the case for this issue is stronger once we have #114, they really are independent.

Btw Lua also spells it “not“ :)

Yes; some parts of zig's syntax are stabilized and this is one of them. I know it doesn't feel good to get your proposal closed but by closing it quickly when I know it is not going to be changed, I'm trying to save your time and everyone else's who participates in the thread, so that you can spend your energy on issues that may ultimately end up having an impact.

Not at all! I’m actually ambivalent; accepting this proposal would imply that language stability is much farther than I would prefer! I am happy that this thread documents the decision for anyone else who might be curious. Thanks!

Was this page helpful?
0 / 5 - 0 ratings