Io has two objects that function as boolean values: true and false. As always, these are just regular objects that you can add things to, etc. (Although why you would want to do that in this case is something else... :-)
false and nil evaluate to false, in a boolean context. Everything else evaluates to true. There seems to be no way to change this. (This is different from, say, Python, where other objects like 0 and [] evaluate to false as well, and this behavior can be changed for custom objects.)
if(3) #=> true if(nil) #=> false
(Note that if can be used this way to get the truth value of an object, kind of like Python's bool(). For regular usage of if, see below.)
if is also just another method. Because of the way Io evaluates arguments, implementing if (and other methods that accept blocks of code) are not special (unlike in many other languages, where it requires special syntax or special form (Lisp)).
if can be used as a "ternary operator" (i.e. it's not an operator in Io, but other languages might use a ternary operator for this, like C's a ? b : c construct):
x := if(a < 3, 100, 200)
It can also be called with two arguments:
x := if(a < 3, 100) # if a >= 3, x will be false
It also accepts code blocks:
if(a < 3,
a := a + 1
writeln("And counting..."), # <-- notice the comma
# "else" block starts here
writeln("Done!")
)
Then, there is the if-then-else construct.
if(a < 3 and b > 5) then(
...code here...
) else(
... code here...
)
elseif is supported as well:
if(a == 3) then(
...
) elseif(b == 5) then(
...
) else(
...
)
It is possible to omit the else part. Interestingly, it is also possible to omit then but not else! This is because if, then and else are all just methods, not special syntactic constructs.
In good Smalltalk (?) tradition, booleans also support ifTrue and ifFalse methods.
(a < 3) ifTrue("yay!" println) ifFalse("boo!" println)
Booleans support the and, or and not methods. (There seems to be no xor.)
While and and or are methods like any others, they can also be used as operators, omitting the parentheses:
a or b a or(b)
There's shortcut behavior:
foo := method(x,
x println
x
)
foo(true) or foo(false)
# evaluates to true; only prints "true"
foo(false) and foo(true)
# evaluates to false; only prints "false"
Similarly, not is a method as well:
true not # --> false false not # --> true (3 == 4) not # --> true