IF Boolean_Logic = Inconsistent Then IsBug()

BlitzMax Forums/BlitzMax Programming/IF Boolean_Logic = Inconsistent Then IsBug()

sswift(Posted 2006) [#1]
If 10 = True 
	Print "(10 = True) = True!"
Else
	Print "(10 = True) = False!"
EndIf
	
If 10 
	Print "10 = True!"
Else
	Print "10 = False!"
EndIf



Both of these should return the same result. Presumably, the second result, because in just about every language out there, 0 = False and anything else = True. But they do not!

Doing something like If (Flags&BIT_CONSTANT = True) results in nothing happening because of this, but If Flags&BIT_CONSTANT will trigger correctly!

And no, this is not due to order of operations unless those are screwed, because If (Flags&BIT_CONSTANT <> 0) does work. So it is not doing this: If Flags&(BIT_CONSTANT = True)


Floyd(Posted 2006) [#2]
True is just another name for 1. This is why the (10 = True) test fails.

This seems reasonable to me. It's exactly the way C/C++ does it.


Dreamora(Posted 2006) [#3]
And yes, BM sees 1 as true, unlike other languages that see 0 as false and "not false means true" for true.


H&K(Posted 2006) [#4]
It does exactly what I thought it should do.

10 does not equal true. Becasue true is a real vale of 1 (as floyd says the same in lots of languages)(I think its -1 in somthing, but cannot remember what)
10 is true (and so is -10), because they dont equal false which is 0
If 10 <> False 
	Print "(10 <> Fasle ) = True!"
Else
	Print "(10 <> False ) = False!"
EndIf
	
If -10 
	Print "-10 = True!"
Else
	Print "-10 = False!"
EndIf
Use this method if it bothers you


sswift(Posted 2006) [#5]
H&K:

But don't you see how crazy that is?

If 10 = False Then Print "10 = False"
If 10 = True Then Print "10 = True"

If 10 <> False Then Print "10 <> False"
If 10 <> True Then Print "10 <> True"

See? The whole thing breaks down! 10 is neither true NOR false!


But anyway that's neither HERE nor THERE. You guys haven't even addressed the issue I pointed out:

If 10 Then Print "10 = True"

You can say that BlitzMax treats 1 as True, but that's clearly not the case here, because the above prints 10 = True. So in one case, BlitzMax considers 10 to be neither true nor false, but in the other it considers anything other than 0 to be true.

It is inconsistent!


H&K(Posted 2006) [#6]
Errr no I dont see how stupid that is. False is a real value of 0, True is a real value of 1

If I compare anything to true Im compareing it to 1

If x= true i.e. If x=1

On the other hand if I just

If x

Im asking if X is true. (Not equal to true, But True)

I think the fundimental problem is the differance between IS TRUE, and IS EQUAL to TRUE. A Difference that, (I am sorry to say), you havent yet grassped

If 10 Then Print "10 = True"

In this case you are asking if 10 is true, which it is, (What it is not is EQUAL to TRUE)


sswift(Posted 2006) [#7]
"On the other hand if I just if x, Im asking if X is true. (Not equal to true, But True)"


But even if you're asking is it IS true rather than whether it is EQUAL to true, X cannot be true if it is NOT equal to True, because the definition of true is being equal to True!

In other languages, from what I remember if something is 0 it is false. If it is NOT 0, then it must be true.


sswift(Posted 2006) [#8]
Floyd:
I think you're wrong, and I found a document which backs me up:

http://72.14.209.104/search?q=cache:D6HAwQzyYDoJ:www.le.ac.uk/cc/tutorials/c/ccccif.html+C+true+%22not+equal+to+0%22&hl=en&gl=us&ct=clnk&cd=1


The reason is that in the C programming language dosen't have a concept of a Boolean variable, i.e. a type class that can be either true or false. Why bother when we can use numerical values. In C true is represented by any numeric value not equal to 0 and false is represented by 0. This fact is usually well hidden and can be ignored, but it does allow you to write

if(a != 0) just as if(a)

because if a isn't zero then this also acts as the value true.



Also this wikipedia page says:
http://72.14.209.104/search?q=cache:DK8fMsuWGZgJ:en.wikipedia.org/wiki/Boolean_datatype+C+true+false+boolean&hl=en&gl=us&ct=clnk&cd=1


In the C programming language, there is no boolean type provided in the C89 (but there is one in C99), but instead true/false values are determined by comparing a value to zero.




H&K(Posted 2006) [#9]
No SSwift the definition of IS EQUAL TO TRUE is "Is the value 1"
The Defintion of "IS TRUE", is a value not 0

And what you have just posted (The not equal to 0 thing), is exactly what we have been saying

But Tell you what. When this tread gets kicked from the bug thread, you can believe us. Till then dont


tonyg(Posted 2006) [#10]



Grey Alien(Posted 2006) [#11]
Tony, there's a bug. Your last If 1 should be If 2 to complete the test.

To be honest I rarely use True/False I always do if something=0 or something<>0 , plus I also do "if something" and "if not something". This seems to work properly (i.e. treat 0 as false and anything non-zero as true) which is fine with me...


Koriolis(Posted 2006) [#12]
@SSwift: No bug here, Floyd is perfectly right. It actually does exactly the same thing as C does, so relying on C to back up the fact that there's be a bug here is a bit awkward.
The key thing is that there is no such thing as a boolean type in BlitzMax, like in C. False and True are integer constants, and boolean operators actually work on integers, not on true bools.

By example, Not (Not (x)) isn't the same as x in BlitzMax or C, even though in boolean logic it is.


Dreamora(Posted 2006) [#13]
Koriolis: Not fully true. With 0 and 1 not(not x) = x in BM.

Although normally most a substraction trick to toggle between values ( a = X - a toggles between 0 and a if a = X or 0 or it toggles between 2 values that sum up to X )


Floyd(Posted 2006) [#14]
The general form is

If expression Then DoSomething

The expression is evaluated. If the value is nonzero then DoSomething is executed.

A conditional such as x<y evaluates to 1 if x is less than y and to 0 otherwise.


Koriolis(Posted 2006) [#15]
Koriolis: Not fully true. With 0 and 1 not(not x) = x in BM.
x is a variable, so I thought it was clear I was saying there is no equality (in the mathematical sense). So to make it clearer: both *expressions* are different. The fact that for 0 and 1 it works is a very minimum and is hardly relevant here.
If x was of a true boolean type, both expression would be simply identical (Not Not x is then an identity, as you'd expect).


Dreamora(Posted 2006) [#16]
Why is it hardly relevant? Booleans are, per definition, 0 and 1.
So in BM, Not(not x) IS equal to x for the set of booleans which is {0,1}

Those 2 are the only ones where not is defined as boolean operations so I don't know what your problem is.
(I know that with higher logics this isn't true, but programming languages only know of 0 and 1, not of the other 3 - 6 states that exist in reality. Those operations define not etc through matrices which define what not x is)


tonyg(Posted 2006) [#17]
Thanks GA, edited the code.
Not sure what the result should be in some strange world of boolean notnot monsters but the results match what I'd expect.


MrCredo(Posted 2006) [#18]
IF (value<>10)=TRUE THEN ........
IF (value=10)=TRUE THEN ........


H&K(Posted 2006) [#19]
But you dont need the =true bit, its inherint in the if. And I think (Though not sure), that it would be slower.
IF value<>10 THEN ........
IF value= 10 THEN ........
Edit, Thats probably what you were showing wasnt it


marksibly(Posted 2006) [#20]
This is by design/expected behaviour/how lots of other languages work etc.


sswift(Posted 2006) [#21]
But is it how _C_ works?


Dreamora(Posted 2006) [#22]
Why should it?
Thought it was called BM and not C? :-)


Byteemoz(Posted 2006) [#23]
But is it how _C_ works?

It is...
#include <stdio.h>
#include <stdbool.h>

int main(){
	if(10==true)
		printf("(10 == true) = True!\n");
	else
		printf("(10 == true) = False!\n");
	
	if(10)
		printf("10 = True!\n");
	else
		printf("10 = False!\n");
}
Result:
(10 == true) = False!
10 = True!



sswift(Posted 2006) [#24]
Byte:
What are you doing that in? C? C++? What compiler? I cna't even get it to compile in Visual C++ but I never use the thing and there's so many confusing options I have no idea where to paste it to run it.

If what you say is true, then this Wikipedia entry is wrong:
http://en.wikipedia.org/wiki/Bitwise_operators


In C and C++, a numerical value is interpreted as "true" if it is non-zero.




Dreamora(Posted 2006) [#25]
I would guess with the compiler you already need for BM ie GCC 3.4 (mingw 5).
VC++ 2005 thought should handle it equaly. older versions might handle it differently. (The C++ stuff changed a little lately)

but even if those two behave not the same: That is a C thing and has nothing to do with BM. It is as it is with BM and is meant to be this way.


H&K(Posted 2006) [#26]
@SSwift

From me. 4th post
10 is true (and so is -10), because they dont equal false which is 0

From you Post above.
If what you say is true, then this Wikipedia entry is wrong:
en.wikipedia.org/wiki/Bitwise_operators
In C and C++, a numerical value is interpreted as "true" if it is non-zero.
Can you not see that everyone (Including Wikipedia), have been saying the same thing

There are two different things here,
1)If X. Is a variable true. In the Old days you would take this to mean "Does X exist", but now with all the NULL stuff its taken to mean does X = a real non False value.
so
If X then.... Means IF X <> FALSE

2)If X = TRUE. Is a variable equal to true. This is not asking does the variable exist. It is simply asking does x equal the arbitary value of TRUE, which in this case is 1

Now just because a variable IS true doesnt mean it equals TRUE.

Remember. True and False, are simply constants that make passing pass or fail flags from functions easyer


sswift(Posted 2006) [#27]
Okay...

I understand now that 10 = True is comparing 10 to the constant True, and the constant True is 1, so they are not equal.

But it is still confusing and _seemingly_ (though perhaps not actually) inconsistent. From a comparing-one-value-to-another point of view it is consistent, but from a I-want-to-know-if-this-variable-is-true standpoint, it is seemingly inconsistent.

It would seem to me that if this is the case, then writing If X = True or If X = False is bad form, because you want to know if X is True, not if X is = True. While in many cases you might get the result you want because X will equal True when it is true, in many cases X will not equal True when it is true. (true in the sense that "If X" returns true for the value of X.)

So you should never do If X = True, or If X = False, but should instead do If X and If Not X.

Actually, what should probably be done is the opposite... If X should pop up a runtime error if X is not True or False, so that you are instead forced to use the correct form of If X <> 0 or whatever, since it is obviously and integer and not a boolean. I suspect this was not done in C++/Max for backards compatability reasons?

In other words, the format for If should be "If Value:Boolean" and if you attempt to pass an integer to it then it errors. If you want to know if an image exists, then instead of doing "If Image" you'd be forced to do "If Image = Null".

Oh and I've found that this works as expected:
If (Flags&Bit) And (Blah = True) Then Print "true"

Flags&Bit apparently gets converted to a boolean for the purpouse of And.

Hm... Well this has been an interesting discussion. I guess I was wrong about how C does things but in my defense I haven't coded in C in 10 years and If X working while If X = True not working is confusing. I was right about the True = Not False bit being in there, just not when it's used.


H&K(Posted 2006) [#28]
Honestly sswift thats why we used to say "If X" ment "does x exist"

This was when this whole NULL thing didnt exist. Either the variable had a value or it didnt, and a newlycreated variable had a value of 0.

We were wrong to call it this, but it ment that we never got mixed-up, and is the reason we dont even see it as a problem doing it this way

The thing is what is it you want to mean by False/True
Because after all even 0 is a true value

Maybe if x=NAN (ie if x is a non numerical value)
But then when would you use this? When X was NULL? so Maybe
If x=NULL?


Byteemoz(Posted 2006) [#29]
What are you doing that in? C? C++? What compiler? I cna't even get it to compile in Visual C++ but I never use the thing and there's so many confusing options I have no idea where to paste it to run it.
I opened the IDE (on my Mac), created a new file, saved it as "test1.c", hacked the code and hit F5...
This should work on Windows (with MinGW) and Linux, too.
-- Byteemoz


Koriolis(Posted 2006) [#30]
Why is it hardly relevant? Booleans are, per definition, 0 and 1.
So in BM, Not(not x) IS equal to x for the set of booleans which is {0,1}
The point was precisely that there is no such thing as a boolean type in BlitzMax
(just like in C/C+) which is the reason why both expressions are different. For 2 expressions to be equivalent, you must for each possible of input values, have the same output values. Here you don't.
I thought this was illustrative of the SSwift's issue, because this is the very same problem : the input values don't lie in the {0, 1} set (that 10 there) so we're not in strict boolean logic anymore, hence the irrelevancy of your remark here. If we were using true booleans, the initial problem he pointed couldn't indeed arise.

@SSwift: you're right, this can be confusng, and having a true boolean type is desirable. There's a good reason to have a true boolean type in languages like C#. But it's realtively easy to live without.


Curtastic(Posted 2006) [#31]

If X should pop up a runtime error if X is not True or False

Thats a good idea.

True and False are more for assinging boolean variables. It just makes it look better.
like:
jumping=True
jumping=False
If jumping Then
If Not jumping Then


FlameDuck(Posted 2006) [#32]
What are you doing that in? C?
Yes.

If what you say is true, then this Wikipedia entry is wrong:
No it isn't. 10==true should evaluate to false because 10 is not litterally equal to true (which has a litteral value of either 1 or -1 [can't remember which]).

Why is it hardly relevant? Booleans are, per definition, 0 and 1.
No they aren't. By definition booleans do not have numerical representation (they are either true or false - a statement like 'x=10' is either true or false, it is not 1 or 0).

However a computer doesn't work that way, so you have to approximate it. Thus false is generally approximated to 0, and true is approximated to being "not false".

Thus if you want to find out if a variable = true, the correct expression you're looking for is whether x <> false.


H&K(Posted 2006) [#33]
@curtastic
If X should pop up a runtime error if X is not True or False

Thats a good idea
It might, (possibly), have been a good idea to have started like that. It is definitly NOT a good idea to change it now


FlameDuck(Posted 2006) [#34]
It's a rubbish idea. True and False are ultimates. How can something not be either true or false?


H&K(Posted 2006) [#35]
NULL

(But I agree with you that its a stupid idea)


sswift(Posted 2006) [#36]
"It's a rubbish idea. True and False are ultimates. How can something not be either true or false?"

I suppose you dislike the idea of NaN as well and think we should just set that to 0.

Something can easily not be true or false if it is not a Boolean.

What number is "Orange"?

If I do this:

SuperStrict
Local A% = "Orange"

I get an error. How can a string not be a number! You are asking the same nonsensical question. A boolean is a boolean, and an int is an int. If you ask is A% true, then it is perfectly reasonable to give an error similar to that which the above code does and have the compiler say "cannto convert from int to boolean" just as it says "cannot convert from string to int".

Ints are not booleans, and vice versa.

Of course Max has no boolean type, so it is a moot point.


FlameDuck(Posted 2006) [#37]
I suppose you dislike the idea of NaN as well and think we should just set that to 0.
No, because a) NaN and Inf are both mathematical concepts (NaN is usually a expression of a complex number).

What number is "Orange"?
That's my point. Yours is When is "Orange" not "Orange".
If "sswift"
	Print "Strings can be true aswell"
EndIf

If Null
	Print "And false aswell"
EndIf
You'll notice that both above examples are functionally equivalent of if true, and if false repectively.

Ints are not booleans, and vice versa.
Thank you for reitterating my point above. However you seem to be confused between what constitutes a boolean value (true or false) and a boolean expression.

If 10 (or even if "10") gives a true result, not because 10 has a boolean value of true, but because the boolean expression 10, evaluates to true.

I think you need to read up on your Boolean Algebra.


H&K(Posted 2006) [#38]
@Flame,

I hope your not trying to include me in your tellingoff, to cite
If Null
	Print "And false aswell"
EndIf
All your post showed was that NULL returns as false.
Which does not disprove that it really is something that should return neither True Nor False. (From my understanding you are in fact just showing that the memory pointed to by the pointer NULL, is zero. <This might be totaly wrong>)

If you weren't telling me off, then yes quite right, how wrong can that sswift be ;-)


sswift(Posted 2006) [#39]
"Thank you for reitterating my point above. However you seem to be confused between what constitutes a boolean value (true or false) and a boolean expression."

Have you been reading my posts, or are you still arguing about what I said in my initial post? If you have been keeping up to date then on what point do you think I am confused here?


"If 10 (or even if "10") gives a true result, not because 10 has a boolean value of true, but because the boolean expression 10, evaluates to true."

I know that.

But that's not what I asked in my more recent posts. I asked why does 10 evaluate to true, rather than erroring?

The number 10 is neither true nor false, so why does it evaluate to true? Declaring it to evaluate to true is arbitrary. Why is 10 true, but 0 false? They are both integers, which are neither true nor false.

I hope you realise that at this point I am speaking in hypotheticals of how the language should perhaps work, and not how I think it actually DOES work. I understand how it does work, and that 10 evaluates to true because it is not 0. But what I am asking is if that makes sense to do. It might be convenient, but it is confusing and nonsensical.


Defoc8(Posted 2006) [#40]
The simplest explanation is that processors usually have a
zero bit in a flags register..branching on zero or none zero
is faster than comparing specific none zero values...
There are probably millions of reasons..but i cant be
bothered to think about it...anyway its handy, i like it.


H&K(Posted 2006) [#41]
@Defoc ;)

What I think sswift if asking, is why the compiler (Not the code/executable), is letting him compare the "Conceptual" True (or false), with an Int (For example)

What Hes sudjesting isnt away for the code to run differently, but rather a sort of "SuperTypeConverstionStrict", that doesnt allow Type True/False to Type Int

It makes a lot of sence, since
If X
would still return TRUE or FALSE. And
If (x=10)
would still return TRUE. But
If X=True
would produce an error

He is right. (Not since the top, but since the thread changed from "This is a bug" to "Could it be done a different way"). It would make more sence to ban non-explicite Int to Bool (Even though we havent got bool, thats what is happening). And then we wouldnt have the problem of
X:Int = 10
If X=True ......
Being False


FlameDuck(Posted 2006) [#42]
I hope your not trying to include me in your tellingoff
Not really, no. Null represents an object (or String) that doesn't exist, so from a semantical point it makes sense that when objects are evaluated as a boolean expression, objects that exist return true, while objects that don't return false. I agree that Null (as a value, if we can call it that) is neither inherently true or false. However it does obtain boolean significance when evaluated in a specific context. The same is true for numbers.

The number 10 is neither true nor false, so why does it evaluate to true?
Because the expression 10 evaluates to true.

Why is 10 true, but 0 false?
Because '10' belongs to the set of integers that, when used as an expression, in most computer languages evaluates to true, where as '0' does not. It's not really arbitrary, it's how (as Defoc8 pointed out) the CPUs instruction set is hardwired.

If it's any consolation, the OS works exactly oposite. In the OS, a returncode of "0" usually means success where as increasingly large numbers represent increasingly severe errors.


H&K(Posted 2006) [#43]
@Flame
Because the expression 10 evaluates to true
That is what Sswift is complaining about
If 10=True.....
Is false. I know thats not what you ment. But its what sswift is talking about

What he is saying is; If "If 10=True", is false, why is "If X", true when it equals 10, rather than the compiler saying "Hang on 10 isnt true or false, whats up 'ear then?".
He is infact asking why we dont all change to this style, whereby an INT (Or float) cannot be compared to TRUE or FALSE. (They CAN BE as in If X, just not compare to as in If X=True)


Russell(Posted 2006) [#44]
...<wack! wack wack!!>...

And the body of the dead horse we've been beating remains dead. ;)

Russell


sswift(Posted 2006) [#45]
"Because '10' belongs to the set of integers that, when used as an expression, in most computer languages evaluates to true, where as '0' does not. It's not really arbitrary, it's how (as Defoc8 pointed out) the CPUs instruction set is hardwired."

No it's not. I used to code in assembly language. There is no boolean in ASM, and therefore there is no hardwired need to have 10 evaluate to true.

While it is true that it might be faster to ask if a variable is not 0 in ASM, rather than ask if it is 0 or 1, or some other value, one could just as easily have made 0 = True, and everything else = False.

But anyway, it is arbirtrary in the sense of logic. I know there is a reason for it, but this would not affect the underlying code. Disallowing conversion from Int to Boolean would be something done at compile time. Internally it would still be using integer comparisons > 0 to look for true booleans, but externally, that would be hidden and forbidden.


" ...<wack! wack wack!!>..."

Yes, you're right, this argument is pointless because BltizMax isn't gonan get changed, but it's an interesting thing I hadn't thought about before, and it makes sense to fix it in future languages. I don't know why it has persisted this long.


FlameDuck(Posted 2006) [#46]
I used to code in assembly language.
Sure.

There is no boolean in ASM
There are actually. The CPU has a bunch of flags (on the Intel x86 stored in the flag register), that holds the current state of the CPU. Every one of those flags is boolean. Either true or false, set or reset. These flags are manipulated by certain instructions, like shifting and adding for instance will effect the "Carry" and "Overflow" flags, CMP (compare) will effect the "Zero" flag Defoc8 was talking about, subtracting the two values it takes as parameters and modifying the flagregister depending on the result. If the result is Zero (ie both numbers are equal) then the Zero flag is set and the next jz (jump if zero) or jnz (jump if not zero) will act accordingly.

Disallowing conversion from Int to Boolean would be something done at compile time.
Ints are not being converted to booleans.

I don't know why it has persisted this long.
Because no-one has created a computer that can read your mind yet. A computer will do what you tell it to, not what you think you tell it to.


sswift(Posted 2006) [#47]
"Ints are not being converted to booleans"

Not in the compiler AS IT IS, no.

But it would be something that could be done at compile time, just as with any other type conversion which is dissalowed. If BlitzMax had a boolean type. Which it does not. But that doesn't mean it would be a bad idea to have one.

"Because no-one has created a computer that can read your mind yet. A computer will do what you tell it to, not what you think you tell it to."

Flameduck, are you intentionally being difficult or what?

There's no mind reading that needs go on here.


If I can do the following:

Function Blah(X:Boolean)

And get an error "cannot convert from int to boolean" when I pass it an int, then the same could be done for an IF statement.

There's no mind reading required.

10 > 5 is a boolean expression and would be evaluated as such, and converted to a boolean type, then passed to the if statement.

10 is not a boolean expression. It is just an integer. There is no > operator to cause it to be converted to a boolean type internally.

So If 10 would error, and 10 10 > 5 would not.

So show me an example where the compiler would need to guess. The compiler doesn't need to guess when you write 10 / 1.5. It converts to a float. This is the same thing.

In fact, if I'm not mistaken someone mentioned C# doing something like this. If that is the case then you're clearly wrong and it is not impossible or would require the compiler to guess.


Smurftra(Posted 2006) [#48]
why not use

10 <> False

then you are sure it will work :), or

not not 10 = true ;)

I agree with sswift that i find it ackward, but i come from Visual Basic, where = True means <> False (so 10 = true is true)

I also understand the reasoning and the difference between 10 = True (10 = 1) and 10 is true

question: there is no operator 'IS' in blitzmax, so if i want to actually write the word TRUE for easy reading of code, what should i write if 10 = true doesnt work?


tonyg(Posted 2006) [#49]
If 10 'TRUE
or
If 10 'IS TRUE


Smurftra(Posted 2006) [#50]
clever, but 1) I use blide and i would want True to be highlighted as it should (My problem, i know), and 2) I use THEN out of habit from VB.