Zig: Support ^ operator with bools

Created on 26 Nov 2020  路  7Comments  路  Source: ziglang/zig

For complex predicates where you want to check if two conditions are different, it's more straightforward to write:

if (some_long_predicate() ^ some_other_long_predicate()) {
  // ...
}

than

if ((some_long_predicate() || some_other_long_predicate() && !(some_long_predicate() && some_other_long_predicate()) {
  // ...
}

especially if you only want to evaluate the predicates once.

If using this bitwise operator with bools is undesirable for some reason, a keyword operator xor similar to and and or could be added.

(Current compiler behavior:

./src/repro_xor.zig:12:12: error: expected token ')', found '=='
        if (thing == null ^ other_thing == null) {

)

Note that this works trivially in C because bool is implicitly convertible to int. To do the same conversion in zig we would have to write @boolToInt around each predicate and compare the result of the xor to 1.

proposal

Most helpful comment

!= is the same as boolean xor but the intent is a bit less readable

if (some_long_predicate() != some_other_long_predicate()) {
  // ...
}

All 7 comments

!= is the same as boolean xor but the intent is a bit less readable

if (some_long_predicate() != some_other_long_predicate()) {
  // ...
}

It's good to know that xor is just not-equal (!=) while xnor is equals (==).

Actually, I believe using and, or, xor and a combination of negating inputs and negating outputs gives the full set of two variable Boolean functions, other than the trivial ones like always true and always one, or ones which simplify down to a single variable (not dependant on one of the inputs) [Comma operator rolling in its grave rn]. With a few redundant ways of doing things.

Some of the more useful ones:

A nand B = not ( A and B ) = not(A) or not(B)
A nor B = not( A or B ) = not(A) and not(B)
A implies B = not(A) or B

Technically a duplicate of #5805 , which was marked as "closed".
Bit operators were however considered for vectors of bool, and for uniformity potentially all bool, but then I don't think that follow-up proposal was ever opened.

!= is the same as boolean xor but the intent is a bit less readable

For the intent in the OP, "check if two conditions are _different_", to me != looks __more__ readable than ^.
What looks unusual to me however is composing multiple: a != b != c != d vs a ^ b ^ c ^ d

For keywords, note that currently Zig keywords influence control flow (short-circuit and and or, the only exception to this are function calls), while symbol operators don't (regular & and |).
As xor cannot be short-circuit-evaluated, a keyword would go against the convention up to now.

Hi,

A small comment about : a != b != c != d vs a ^ b ^ c ^ d

I might agree readable yes but "a != b != c != d" is more how mathematics would write it.

Assumption : At time C was built it was mostly by people doing lot of math for software engineering, and Zig = C fixed so going forward with how we would write it in mathematics makes sens.

Let me know what you think.

Kinds regards

"a != b != c != d" is more how mathematics would write it.

AFAIK in mathematics this would imply a != b and b != c and c != d, but in Zig this is equivalent to (a != b or c != d) and (a == b or c == d)

Yes, you are right.
Thank you

No ^ operator with bools

Was this page helpful?
0 / 5 - 0 ratings

Related issues

fengb picture fengb  路  3Comments

S0urc3C0de picture S0urc3C0de  路  3Comments

jorangreef picture jorangreef  路  3Comments

bheads picture bheads  路  3Comments

komuw picture komuw  路  3Comments