Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: xor operator for bool type #5805

Closed
data-man opened this issue Jul 6, 2020 · 12 comments
Closed

Proposal: xor operator for bool type #5805

data-man opened this issue Jul 6, 2020 · 12 comments
Labels
proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Milestone

Comments

@data-man
Copy link
Contributor

data-man commented Jul 6, 2020

Many languages support it.
It would be nice if Zig will support this operator, too.

test "bool operators" {
    expect(!(!true));
    expect(!false);

    expect(true and true);
    expect(!(true and false));
    expect(!(false and true));
    expect(!(false and false));

    expect(true or true);
    expect(true or false);
    expect(false or true);
    expect(!(false or false));

    expect(!(true xor true));
    expect(true xor false);
    expect(false xor true);
    expect(!(false xor false));
}

I implemented it (mostly) in xor_bool branch. Except for documentation and code generation.
I hope that core developers can finished my work.

@data-man
Copy link
Contributor Author

data-man commented Jul 6, 2020

Results of voting in Telegram channel:

xor is needed? %
yes 87
no 0
why? 13

Yes, the small community (voted by 8 users) 😄

@Vexu Vexu added the proposal This issue suggests modifications. If it also has the "accepted" label then it is planned. label Jul 6, 2020
@Vexu Vexu added this to the 0.7.0 milestone Jul 6, 2020
@rohlem
Copy link
Contributor

rohlem commented Jul 6, 2020

Just wanted to point out some things:
So far Zig uses keywords instead of operands if they influence control flow; in the case of boolean operators, they short-circuit: false and and true or never evaluate the second operand.
Xor cannot short-circuit, so if we stick to above rule, an operator symbol would be more appropriate.

Also note that boolean-xor is equivalent in behaviour to !=, which is already implemented for bool operands. This makes it feel superfluous to me personally (one way to do things).

@data-man
Copy link
Contributor Author

data-man commented Jul 6, 2020

one way to do things

That's always a funny point.

What's your choice?
@sin or math.sin?
@cos or math.cos?
... and so on.

@data-man
Copy link
Contributor Author

data-man commented Jul 6, 2020

Also note that boolean-xor is equivalent in behaviour to !=

const std = @import("std");
const warn = std.debug.warn;
const Vector = std.meta.Vector;

pub fn main () void {
    const v1: Vector(4, bool) = [_]bool{ true, false, true, false };
    const v2: Vector(4, bool) = [_]bool{ false, false, true, false };
//      const v3 = v1 ^ v2; //it isn't compiles
    const v4 = v1 != v2;
//                ^ this

    warn("v1 = {}\n", .{ v1 });
    warn("v2 = {}\n", .{ v2 });
//      warn("v3 = {}\n", .{ v3 });
    warn("v4 = {}\n", .{ v4 });
}

@Sobeston
Copy link
Contributor

Sobeston commented Jul 6, 2020

That's always a funny point.

We will never be able to actually only have one way of doing things - that would be ridiculous; no programming language could do this. But do not let perfection get in the way of good - we can still confidently aim towards this (impossible) goal. We should at the very least try not to go in the opposite direction.

Introducing an operator that does the exact same thing as != doesn't make sense.

I also do not see the problem with your example - v4 works fine.

@data-man
Copy link
Contributor Author

data-man commented Jul 6, 2020

v4 works fine

Yes.
But users expect comparison of vectors, so it's one vector equal to another or not.

@Snektron
Copy link
Collaborator

Snektron commented Jul 6, 2020

I believe vector equality comparison to check whether all elements are equal rather than performing the operation lane-wise is handled by #2698.

@SpexGuy
Copy link
Contributor

SpexGuy commented Jul 6, 2020

It shouldn't be unexpected that != on Vector is per-component. It represents a SIMD vector. All operations are per-component by design. Having != be per-component will likely not change. Maybe we should rename Vector to something else like Parallel or Multi to eliminate this confusion.

@data-man
Copy link
Contributor Author

data-man commented Jul 6, 2020

It shouldn't be unexpected that != on Vector is per-component.

Why?

(1 != 2) == true
(true != false) == true
(v1 != v2) == true // oops!

@SpexGuy
Copy link
Contributor

SpexGuy commented Jul 6, 2020

A SIMD vector is not one value. It is a bundle of parallel values. Applying any operator to a SIMD vector applies it to each element in the bundle. This includes +, -, *, /, %, !, [x] (when x is a Vector), ==, !=, >, <, >=, and <=. There are no base operators on a SIMD vector that can combine information from multiple lanes. Which makes sense based on the design of SIMD - it carries multiple channels of independent data (Multiple Data), where each channel has the same meaning (Single Instruction). Checking that all elements of a SIMD vector are a certain value is a rare operation, much more rare than generating a mask of channels where a condition applies.

As another argument, consider != vs >=. It's clear that x >= y should produce a vector when x and y are vectors, because there isn't a good way to define this operator to return a single value. Why should != and == be different from >= and <?

Finally, an xor operation would only resolve this case for Vector(N, bool). If != were changed to check all channels, how would you do a per-element != for a Vector(N, u32)?

@data-man
Copy link
Contributor Author

data-man commented Jul 6, 2020

Checking that all elements of a SIMD vector are a certain value is a rare operation

Because of its "rarity", I implemented comparison of vectors in meta and testing. ;)

Finally, an xor operation would only resolve this case for Vector(N, bool).

Maybe not a new operator, but an implementation ^ for boolean vectors.

@andrewrk andrewrk closed this as completed Jul 7, 2020
@andrewrk
Copy link
Member

andrewrk commented Jul 7, 2020

Maybe not a new operator, but an implementation ^ for boolean vectors.

I think there is a good case to be made for allowing bitwise operators on bool, or at least on vectors of bool. I thought there might have been a separate proposal for that, but I did not find one. Would you like to make that proposal, @data-man?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Projects
None yet
Development

No branches or pull requests

7 participants