Flow Control

Magpie doesn't shy away from imperative programming, so it supports the usual flow control structures you know and love, although it does try to spice them up a bit. Before we cover them, there's one minor point to cover first:

Truthiness

Flow control is about evaluating an expression and then choosing an action based on whether or not the result is "true". That's easy if the value happens to be a boolean, but what if it's some other class?

Most languages handle this by having a set of rules for what values of any given type are "true" or not. Magpie calls this "truthiness". By default, the rules are:

However, this behavior isn't fixed. Truthiness is determined by sending a true? message to the object. The value returned by that is used to determine if a condition is met or not. So, if you define your own class, you can control how it behaves when used in a conditional expression by simply defining true? to do what you want. (To avoid the turtles-all-the-way-down problem, the result from true? does have a fixed interpretation: a boolean true is the only truthy value.)

When reading the rest of this section, understand that any time a condition is evaluated, there is an implicit call to true? inserted. So this:

if something(other) then ...

Is really:

if something(other) true? then ...

if/then/else

The simplest flow control structure, if lets you conditionally skip a chunk of code. It looks like this:

if ready then go!

That will evaluate the expression after if. If it's true, then the expression after then is evaluated. Otherwise it is skipped. The then expression can be a block:

if ready then
    getSet
    go!
end

You may also provide an else expression. It will be evaluated if the condition is false:

if ready then go! else notReady

And, of course, it can take a block too. Note that if you have an else clause, and the then takes a block, you do not need an explicit end for the first block. The else will imply that:

if ready then
    getSet
    go!
else
    notReady
end

Since Magpie does not have statements, even flow control structures are expressions and return values. An if expression returns the value of the then expression if the condition was true, or the else expression if false. If there is no else block and the condition was false, it returns nothing.

print(if true then "yes" else "no") // Prints "yes".

(This also means that Magpie has no need for a C-style ternary operator. if is the ternary operator.)

Conjunctions

What other languages call "logical operators", Magpie calls "conjunctions". They are considered flow control expressions and not operators because they conditionally execute some code— they short-circuit. There are two conjunctions in Magpie: and and or. Both of them are infix operators, like so:

happy and knowIt
ready or not

An and conjunction evaluates the left-hand argument. If it's not true, it returns that value. Otherwise it evaluates and returns the right-hand argument. An or conjunction is reversed. If the left-hand argument is true, it's returned, otherwise the right-hand argument is evaluated and returned:

print(0 and 1) // prints 0
print(1 and 2) // prints 2
print(0 or 1)  // prints 1
print(1 or 2)  // prints 1

Note that logical negation is not a built-in flow control expression. Instead, not is simply a method on booleans:

if happy not then print("sad")

"xor" doesn't really need to be a conjunction since it doesn't short circuit, but it (and maybe "not") likely will be at some point just to be consistent.