• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!
  • Hello [name]! Thanks for joining the GMC. Before making any posts in the Tech Support forum, can we suggest you read the forum rules? These are simple guidelines that we ask you to follow so that you can get the best help possible for your issue.

if (variable == (A||B)) something - does not work

D

digimbyte

Guest
as the title says, I painfully scratched my head but found game maker unable to compare; A or B or C and instead had to write it out.

Normally in other programming languages, I would simply group things like so
if (textAlign == (1||4||7))
textHAlign = fa_left;
Sadly, that does not work.
The current solution is to write in full
if (textAlign == 1||textAlign == 4||textAlign == 7)
textHAlign = fa_left;

can this be fixed?
 

Roderick

Member
1||4||7 is the same as applying the Boolean Or to 1, 4, and 7.

001 OR 100 OR 111 = 111 (Decimal 7), so your code is effectively the same as if (textAlign == 7).

Just like math, you have to take the order of operations into account; in this case, the expression is evaluated before the equivalence is checked. The fact that you put (1||4||7) in parentheses just reinforces the need for it to be evaluated first.

While I'm sure there are exceptions, every language I've used works this way.

Edit: My mistake, | is Boolean Or, || is an equivalence, so removing the parentheses might work. I haven't tested, so I can't say for sure.
 

FrostyCat

Redemption Seeker
as the title says, I painfully scratched my head but found game maker unable to compare; A or B or C and instead had to write it out.

Normally in other programming languages, I would simply group things like so
if (textAlign == (1||4||7))
textHAlign = fa_left;
Sadly, that does not work.
The current solution is to write in full
if (textAlign == 1||textAlign == 4||textAlign == 7)
textHAlign = fa_left;

can this be fixed?
No programming language I know of allows comparisons to be handled like that using ||.

There may be lookalikes such as this from Python:
Code:
if textAlign in [1, 4, 7]:
But these are based on logically correct usage of existing operators, not made-up crap like what you proposed.

This doesn't need "fixing". What really needs fixing is your misguided understanding of Boolean operators.

1||4||7 is the same as applying the Boolean Or to 1, 4, and 7.

001 OR 100 OR 111 = 111 (Decimal 7), so your code is effectively the same as if (textAlign == 7).

Just like math, you have to take the order of operations into account; in this case, the expression is evaluated before the equivalence is checked. The fact that you put (1||4||7) in parentheses just reinforces the need for it to be evaluated first.

While I'm sure there are exceptions, every language I've used works this way.
This is just as wrong.

|| is the Boolean OR, it will cast its operands to Boolean before evaluation. Here it will cast 1, 4 and 7 all to true, then give you true as a result. What you are talking about is |, the bitwise OR.
 

Coded Games

Member
Out of the 5 programming languages I have experience with I've never seen an if statement written that way. What language does allow that?
 
D

digimbyte

Guest
sorry to upset some people, didn't know coding contradictions can be like religion around here. looking at you Frosty.
In my defense, I have been using LSL for the last 3 years, and they accept if statements like so
Code:
if (variable == (1|2|3)) something
Before that I previously came from Unity, coding in C# which was where I started learning.
 

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
You can make a script like so,
Code:
/// either(value, ...values)
var v = argument[0], i = 0;
repeat (argument_count - 1) {
    if (v == argument[++i]) return true;
}
return false;
And then do
Code:
if (either(variable, 1, 2, 3)) { ... }
I believe this is the closest it gets in terms of simple solutions.
 

Nux

GameMaker Staff
GameMaker Dev.
Visual Basic allows pseudo whitelisting:
Code:
Dim argument as integer = console.readkey()
if ( {1,3,7}.contains(argument) ) then
    ' do stuff
end if
... Unfortunately, I don't think this is possible in GML.
 

FrostyCat

Redemption Seeker
sorry to upset some people, didn't know coding contradictions can be like religion around here. looking at you Frosty.
In my defense, I have been using LSL for the last 3 years, and they accept if statements like so
Code:
if (variable == (1|2|3)) something
Before that I previously came from Unity, coding in C# which was where I started learning.
Just because a piece of code is syntactically correct, it doesn't mean it does what you think it does (i.e. logically correct). And flukes don't count.

In both LSL and C#, their | operators do exactly what Roderick described, bitwise OR. The condition in your example is therefore equivalent to variable == 3, not only in GML but also in LSL and C#. With variable set to 3 of course it would look like it worked, but punch 1 or 2 in there and smell the coffee yourself.

For someone claiming 3 years of LSL experience and even more in C#, you certainly don't think like one.
 
D

digimbyte

Guest
For someone claiming 3 years of LSL experience and even more in C#, you certainly don't think like one.
sounds like your too busy trying to discredit my own experience instead of trying to look at it objectively.
can't we just agree to dissagree?
It's easier to say that GML's integrated parser doesn't have that when compiling code, then assume that the parser won't get updated because why bother?
 
Last edited by a moderator:
H

Homunculus

Guest
sounds like your too busy trying to discredit my own experience instead of trying to look at it objectively.
can't we just agree to dissagree?
It's easier to say that GML's integrated parser doesn't have that when compiling code, then assume that the parser won't get updated because why bother?
Why would you assume that a == b||c||d not being interpreted as a == b || a == c || a == d is a parser error or a missing feature?

I don't know LSL, but in all other languages I know a = b||c||d has a totally different meaning from what you describe, and that is in fact the intended behavior. I wouldn't want it otherwise. The same applies to GML, why should the parser be changed, making this expression different than most popular languages, when it already does what it's supposed to do?
 
Last edited by a moderator:
D

digimbyte

Guest
I'm not saying it's a parser error.
I'm just saying why can't we have it so a == (b|c|d) is equal to a == b || a == c || a == d when being parsed?
the rest of GML incorporates easy and simple pseudo that would normally throw visual studio a fit.

the point is to have clean readable code, so how is this a negative thing?
who doesn't like new features?
 
H

Homunculus

Guest
Well I do agree that it is a common mistake, especially from those new to programming, so it's a fair point you are rising.

But the point is that first of all, that's not the expected behavior of a boolean expression to begin with to those who actually know other languages. Secondly, it's ambiguous: what if I really want to test those as the result of a boolean expression? Imagine a case where you want some code executed only if two set of values are both a true or both false, how do you express that if the parser interprets boolean expressions like you described? Like a || b == c || d .

What could be done to make this easier instead, is a better array management. I'd love to write your expression as something like includes([1,4,7], myval) , but unfortunately we can't declare arrays this way and on the fly
 
Last edited by a moderator:

SnoutUp

Member
Oh, just write a script for it and move on. GML already has enough bad practices as it is. Also, adding something like that to parser might be way more complicated than anyone, who is not making parsers, think, so it could be a huge waste of time and resources for something nobody really needs nor can use anywhere* else. I can see how it could be comfortable and I probably would use it, but I don't need it.

I'm not saying it's a parser error.
I'm just saying why can't we have it so a == (b|c|d) is equal to a == b || a == c || a == d when being parsed?
the rest of GML incorporates easy and simple pseudo that would normally throw visual studio a fit.

the point is to have clean readable code, so how is this a negative thing?
who doesn't like new features?
 

Roderick

Member
I'm just saying why can't we have it so a == (b|c|d) is equal to a == b || a == c || a == d when being parsed?
Because both already have definitions, set long before GML existed. You are asking for an existing standard to be changed to suit your own needs, regardless of all the other people who are currently using it as intended. I'm sure that I'm not the only person who has code that would be broken by your proposal. Bitmasking is a thing.

To extend on your suggestion: 2 + 2 is equal to both 2 x 2 and power(2, 2). Should we change GML so that ALL instances of n + n, n x n, and power(n, n) are equal?

Just because an expression used wrong works in one situation doesn't mean it should work in all situations.
 
Top