What is TRUE?
K2
Posts: 693
The Propeller Manual indicates that TRUE is -1 and FALSE is 0. Under the explanation of the IF command, the manual says that a "valid" condition is one that evaluates to TRUE...
This would seem to be a radical departure from the convention in many other languages, that anything non-zero is considered TRUE and only 0 is FALSE.
Yet if I write this in Spin...
...I become king. What gives?
This would seem to be a radical departure from the convention in many other languages, that anything non-zero is considered TRUE and only 0 is FALSE.
Yet if I write this in Spin...
IF 1 K2 := king
...I become king. What gives?
Comments
It's been a topic of discussion and merriment before.
ZERO is FALSE
Non-ZERO is TRUE
seems to be the general consensus.
-Phil
-1 is used as true so that a bitwise inverse (what NOT does in most languages) will flip it to FALSE (0). If you use another value, not-true isn't false.
But Spin adds another layer, because in Spin NOT returns false for any nonzero input; it's not a bitwise inverse. The bitwise inverse operator is an exclamation mark.
"The Boolean AND operator compares two operands and returns TRUE (-1) if both values are TRUE (non-zero)..."
Here on out, when I encounter "TRUE" in the manual, I will interpret it as I like. This just proves how much simpler PASM is.
Thanks for the explanations and the link to a previous discussion of this.
In Perl, a conditional evaluates to "true" if it's defined and not 0, "", or "0". Every BASIC I've ever seen considers a non-zero value to be true when used in conditionals. Which languages were you referring to that require a conditional to evaluate to -1 before it's true?
-Phil
One thing Spin lacks that I wish it had is lazy Booleans: && and ||. With these, the expression to the right is not executed if the result of the Boolean is already known. They're really handy for creating less verbose code. Another is the ternary conditional expression: result := condition ? evaluate_if_true : evaluate_if_false .
I realize that ||, ?, and : are otherwise deployed. But their additional use in the situations noted above would be syntactically unambiguous.
-Phil
It's not that they interpret $0001 as false, it's that all the logical operations are bitwise and only work right on all-0 and all-1 multibit values. This has been the case for every platform I've ever used, since that's the way it is in assembly language. If you use 1 as TRUE and perform a typical NOT on it you get $FFFE, which is still true.
Abstracting logical operators from their bitwise roots is very useful in high level languages. Perl actually has three "and" operators (and similar for "or"): & (bitwise), && (lazy logical), and and (lazy, lower-precedence logical) -- all of them helpful in their given contexts.
-Phil
We do this all the time, but we don't have that luxury in Spin, for example; hence the distinction between logical and bitwise Booleans. The equivalent in Spin, of course, is
which is way better than having to write if ((a <> 0) | (b <> 0)).
-Phil
I'm washing my hands of it, entirely. :zombie:
The typical syntax for a HLL if statement is given as: IF {condition} THEN {do stuff}. You'll note that {condition} is not specified as to type; it's a generic mathematical expression evaluation, which can result in any 32-bit value, and the typical HLL will interpret any nonzero result as true and {do stuff}. Logical operations like AND, OR, and NOT are just math operators like *, +, and /, except higher on the operator precedence hierarchy. Comparison operators like =, <>, and so on all return -1 for TRUE because if they didn't, further logical operations on their results (like A = 3 OR NOT (B <> 4)) would not work. The reason the HLL does it this way is twofold; first, as I said above that's the instruction provided by the CPU, and second, if the HLL did like Spin and abstracted any nonzero input to TRUE, you couldn't use AND and OR for bitwise mask manipulation. You'd have to provide a different function for that -- which Spin does. But Spin is the only development system I've ever used that does it that way. In most of the world, TRUE is -1 so that the same CPU instructions used for bitwise logical operation can also be used for logical expression evaluation.
I'm a bit confused about the dialog between you and Phil. First of all, it is possible to do the Spin statement "a := b and c", where the values of "b" or "c" don't have to be only 0 or -1. Of course, the result stored in "a" will be either 0 or -1. Also, C uses the value of 1 for TRUE. It is complemented in C with the ! operator, which is a logical operator in C, and not binary. I have also used (1 ^ x) and (1 - x) to complement the logical value in of x in C.
Using -1 for TRUE is nice because you can do something like "a := (x & a) | (!x & b)" in Spin to select either the value of a or b depending on the value of x. I have also done something like "a += x & incr" to conditionally add incr to a depending on the logical value of x. In C, I would do something like "a += x * incr", which is OK if the processor has a single-cycle multiple. An alternate method in C would be "a += (-x) & incr". Of course C also has the ?: operator that provides a better way to do that.
Dave
But even in C, which is about as typical as typical gets for some people, the && and || operators treat any non-zero argument as true and return 1 for true (instead of -1) and 0 for false.
-Phil
In systems which use integer math, of which Spin is sterling example, logical TRUE is minus one or all bits on. Get used to it now, and you won't have to figure out why your code did something strange later.
Dave, in Spin the statement "a := b and c" will coerce b and c to -1 if they are nonzero before doing the bitwise CPU and operation and returning its result. That's interesting about C because Spin is exactly the opposite -- NOT coerces the input to -1 before inverting, and ! does a bitwise one's complement. So one might say Spin is influenced both by Basic and C, but in this regard it hews strongly to BASIC.
Incidentally, it was a primary goal in the design of the standard floating point libraries that the integer minus one be represented by all bits on, and zero by zero; again, this was so that bitwise logical operators would work properly for logical operations. This means that you can place -1 in a floating point variable, execute a CPU bitwise inversion, and you will get 0. So obviously a lot of thought has gone in this direction.
Spin is definitely not strongly typed! (See: http://en.wikipedia.org/wiki/Strong_typing) All expression evaluations are done with longs, whether you want them to or not. It's not even picky about whether the operands are numbers or strings. It may not perform the operation correctly, of course, but the compiler doesn't enforce typing. The only difference between Spin and other non-strongly-typed languages is the choice of the default type for expression evaluation. And, BTW, you can choose integer evaluation in Perl if you want it: http://perldoc.perl.org/integer.html
I've never had a problem with it, nor do I expect I ever will. The way Spin handles things is highly useful.
I'm frankly baffled that this discussion continues. When you find yourself in a hole, it's almost always better to stop digging.
-Phil
And that blows past my main point, which is that Spin doesn't even support array bounds checking, and you're comparing it to Perl? -1 as TRUE is an elegant way to make a generic math expression evaluator handle logical expressions without special cases or operators. It is the only way I would consider developing a system for my own use, and over the years I've developed several. Anything else is a waste of CPU cycles and special-case code.
-Phil