mshell provides control flow constructs for conditional execution and looping.

if / else* / else / end § Back to top

The if block is the primary conditional construct. The condition is evaluated before if and popped from the stack.

true if
    "condition was true" wl
end

Add an else branch for when the condition is false:

false if
    "true branch" wl
else
    "false branch" wl
end

Use else* and *if for else-if chains:

2 n!
@n 1 = if
    "one" wl
else* @n 2 = *if
    "two" wl
else* @n 3 = *if
    "three" wl
else
    "other" wl
end

Conditions can be booleans or integers. For integers, 0 is true (like Unix exit codes), non-zero is false.

0 if "zero is true" wl end
1 if "not printed" wl end

iff § Back to top

iff is a postfix conditional that executes quotations based on a condition. It has two forms: with and without a false branch.

# Two-argument form: condition (true-quote) iff
true ("was true" wl) iff

# Three-argument form: condition (true-quote) (false-quote) iff
false ("true" wl) ("false" wl) iff

iff is useful for inline conditionals:

@count 0 > (@items process) iff

loop § Back to top

loop repeatedly executes a quotation until break is called.

0 i!
(
    @i 5 >= if break end
    @i wl
    @i 1 + i!
) loop

Output:

0
1
2
3
4

break § Back to top

break exits the innermost loop.

0 i!
(
    @i 1 + i!
    @i 3 = if
        "breaking" wl
        break
    end
    @i wl
) loop
"done" wl

Output:

1
2
breaking
done

continue § Back to top

continue skips the rest of the current iteration and starts the next one.

0 i!
(
    @i 5 >= if break end
    @i 1 + i!
    @i 3 = if continue end
    @i wl
) loop

Output (3 is skipped):

1
2
4
5

Prefix Quote Syntax § Back to top

Prefix quotes provide an alternative syntax for applying functions to quotations. The syntax is functionName. ... end, which is equivalent to (...) functionName.

# Traditional postfix syntax
[1 2 3 4 5] (3 >) filter

# Prefix quote syntax
[1 2 3 4 5] filter. 3 > end

Prefix quotes work with any function that expects a quotation, including map, filter, each, and user-defined functions:

# Double each element
[1 2 3] map. 2 * end   # Result: [2 4 6]

# Print each item
["a" "b" "c"] each. wl end

Prefix quotes can be chained:

# Filter positives, then double them
[-1 2 -3 4] filter. 0 > end map. 2 * end   # Result: [4 8]

Prefix quotes can also be nested (one inside another):

# For each sublist, filter elements > 5
[[1 2 3] [4 5 6] [7 8 9]] map. filter. 5 > end end   # Result: [[] [6] [7 8 9]]

This is also useful to turn boolean operators and and or into a more traditional lookup infix format:

true or. false end and. true end # Like (true | false) & true = true