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

Add a boolean XOR operator to GDScript #230

Closed
Chaotikmind opened this issue Nov 14, 2019 · 24 comments
Closed

Add a boolean XOR operator to GDScript #230

Chaotikmind opened this issue Nov 14, 2019 · 24 comments

Comments

@Chaotikmind
Copy link

Describe the project you are working on:
Working on a simple game.

Describe the problem or limitation you are having in your project:
i was just trying to toggle a Panel visibility on and off

Describe how this feature / enhancement will help you overcome this problem or limitation:
It could be written very naturally like any other language, typing that much code for something that simple seems weird and unpractical

Show a mock up screenshots/video or a flow diagram explaining how your proposal will work:
See below

Describe implementation detail for your proposal (in code), if possible:
the syntax could be something like :
$Panel.visible = $Panel.visible ^^ true;
additionally a ^^= operator could be provided
$Panel.visible ^^= true;

If this enhancement will not be used often, can it be worked around with a few lines of script?:
it can definitely be replaced by a few line of script, but it also seems like a decent language should have that operator

Is there a reason why this should be core and not an add-on in the asset library?:
I guess it can't be an addon i that case

@groud
Copy link
Member

groud commented Nov 14, 2019

Well, for booleans, it's basically equivalent to the != operator.

@Chaotikmind
Copy link
Author

I'm so used to ^ in c++ i didn't even think about using != in fact

@Calinou
Copy link
Member

Calinou commented Nov 14, 2019

This can be achieved with the following one-liner:

$Panel.visible = not $Panel.visible

# Or:
$Panel.visible = !$Panel.visible

GDScript also offers the & (AND), | (OR) and ^ (NOT) bitwise operators, which are useful for enabling or disabling flags:

some_texture.flags |= Texture.FLAG_FILTER

@Chaotikmind
Copy link
Author

Chaotikmind commented Nov 14, 2019

Yes, i can agree that my request is not that great in retrospective.
It is just that is seems weird to have the bitwise xor and not the boolean xor
but we can probably all live with that

@bojidar-bg
Copy link

C++ doesn't have a boolean/logical XOR operator either.

@Chaotikmind
Copy link
Author

Yes but you can still use it on bools

@dalexeev
Copy link
Member

The difference between xor and != is that we can't do that:

print(123 != "string") # Error

(See godotengine/godot#26375.)

And this is correct:

print(123 && "string") # True
print(123 || "string") # True

Even if you accept 26375, 123 != "string" must be true.

# print(123 xor "string") # False
print(bool(123) != bool("string")) # False
print(!123 && "string" || 123 && !"string" ) # False

@lukostello
Copy link

While != works in my scenario I don't think ^^ is equal to !=. I tend to think of != and == as having lower priority than && and ||. The way I am thinking about it they always occur last.
false || true ^^ false && false would evaluate to false, while
false || true != false && false would evaluate to true
because false || true != false && false would equal (false || true) ^^ (false && false)
They also have different connotations which make it more readable to use one over the other in certain scenarios as mentioned in previous posts.

@bojidar-bg
Copy link

Mixing the or/|| and and/&& operators is generally discouraged; likewise, mixing them with a xor/^^ operator should be discouraged as well.

@Calinou Calinou changed the title Adding a boolean xor operator to gdscript Add a boolean XOR operator to GDScript Sep 23, 2020
@Calinou
Copy link
Member

Calinou commented Dec 12, 2020

Closing due to lack of support – see the above discussion.

@dalexeev
Copy link
Member

Closing due to lack of support

@Calinou There was not even a vote of Twitter experts on this issue. How can you judge the degree of support by 3 votes?
And besides, there is even a constant for the XOR operator in the Variant.Operator enum:

And while I'm on the subject of operators, this proposal has support:

13 : 0. Where is my exponentiation operator? 😃

As for the division operators, I'm disappointed. I could say a lot, but this topic is not the place for that, and the original discussion is blocked. I just want to say that if 992 people voted against, then this is not a reason to hopelessly block the discussion. A 58 : 42 ratio is not 95 : 5 (moreover, the sample was not representative). With such figures, not the majority should decide, but objective facts.

@dalexeev
Copy link
Member

if object xor condition:
    do_something()

if object xor number:
    do_something()

if object xor vector:
    do_something()

# vs

if is_instance_valid(object) != condition:
    do_something()

if is_instance_valid(object) != bool(number):
    do_something()

if is_instance_valid(object) != (vector != Vector2.ZERO):
    do_something()

@KingDuckZ
Copy link

Ended up here looking for how to do xor on bool. Is the state of this discussion still actual in 2021?

Yeah operator != messes up precedence, I can use it but it's a poor man's replacement for xor (it should be between and and or)

@Calinou
Copy link
Member

Calinou commented Apr 2, 2021

Ended up here looking for how to do xor on bool. Is the state of this discussion still actual in 2021?

Yes, no XOR operator was added in the master branch. It's very unlikely to happen considering this is rarely a needed feature. Languages which have built-in XOR operators are also not that common.

If you really need it often, you can probably write a method for it and expose it in an AutoLoad.

@dalexeev
Copy link
Member

dalexeev commented Apr 2, 2021

It's very unlikely to happen considering this is rarely a needed feature.

OMG, why does XOR bother you so much? Check out my comments above for an explanation of how XOR differs from !=. XOR has a well-defined semantics: a xor b xor c is true if and only if exactly one of the expressions a, b, c is true. Logical XOR has a bitwise counterpart. XOR even has operator code, although it hasn't been implemented yet. What's the problem with XOR?

@Calinou
Copy link
Member

Calinou commented Apr 2, 2021

What's the problem with XOR?

Every feature has a maintenance cost 🙂

We need to balance the number of features versus this cost.

@dalexeev
Copy link
Member

dalexeev commented Apr 2, 2021

Every feature has a maintenance cost

I don't believe that maintaining this feature is too expensive. This is ridiculous. There are many much more controversial features than this unfortunate operator. Arguing that xor is rarely used is like asking to remove rarely used control characters ("\a", "\b", "\f", "\v").

@luislodosm
Copy link

Godot 3.3.1

&= operator doesn't work

example:

var my_bool = true
my_bool &= false

@Calinou
Copy link
Member

Calinou commented May 20, 2021

@luislodosm &= doesn't work with booleans (as it doesn't make sense there), but it works with integers:

var my_bool = 1
my_bool &= 0
print(my_bool)  # 0

@luislodosm
Copy link

It's useful when you need to check multiple conditions, for example:

var all_visible = true
for node in nodes:
  all_visible &= node.visible

if all_visible:
 print("All nodes are visible")
else:
  print("Not all nodes are visible")

@dalexeev
Copy link
Member

dalexeev commented May 20, 2021

You can use:

var all_visible = true
for node in nodes:
    all_visible = all_visible and node.visible
    # Or:
    # all_visible = all_visible && node.visible

You can open a proposal to add &&= and ||=:

var all_visible = true
for node in nodes:
    all_visible &&= node.visible

But we don't need to mix logical and bitwise operators.

print(1 & 1)  # 1
print(1 && 1) # True

@MewPurPur
Copy link

MewPurPur commented Sep 12, 2021

It's useful when you need to check multiple conditions

Can't think of any cases where it'd improve code. This is faster and easy to read:

for node in nodes:
    if not node.visible:
        all_visible = false
        break

@elvisish
Copy link

collision.get("normal").y > 0.99 != get_floor_normal().y > 0.99
doesn't work
collision.get("normal").y > 0.99 ^ get_floor_normal().y > 0.99
doesn't work, we need XOR.

@ghost
Copy link

ghost commented Sep 7, 2022

XOR has a well-defined semantics: a xor b xor c is true if and only if exactly one of the expressions a, b, c is true.

nooo, that's not how XOR works, if a, b and c are all 1 then the result will be 1:

0^0 == 0
0^1 == 1
1^0 == 1
1^1 == 0

a = 1
b = 1
c = 1
a_xor_b = a ^ b
a_xor_b == 0
a_xor_b_xor_c = a_xor_b ^ c
a_xor_b_xor_c == 1

in cryptography there's such a thing as a one-time pad, you generate a stream of random bytes the size of the data you want to encrypt, that stream acts as both encryption and decryption key:

data = 7391677753
key = 1821862970
encdata = data ^ key
encdata == 7851958531
decdata = encdata ^ key
decdata == data

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants