Control flow
Noodle uses structured control flow with explicit delimiters. Conditions must
have type Bool; other values are not treated as truthy or falsey.
if, elsif, and else
Section titled “if, elsif, and else”An if with an else is an expression. Every branch must produce one common
type:
func classify(value : Int) -> String do if value < 0 then "negative" elsif value == 0 then "zero" else "positive" endendOnly the selected condition and branch are evaluated. One end closes the
complete chain.
Without else, the expression has type Unit, so every branch must also
produce Unit:
func announce_if_positive(value : Int) -> Unit do if value > 0 then Console.println("positive"); end;endThree-part for loops
Section titled “Three-part for loops”The familiar header form provides initial state, a test, and a step:
func trace_count(limit : Int) -> Unit do for index = 0; index < limit; index = index + 1 do Debug.trace(index); end;endThe loop variable is an immutable binding for each iteration. The step creates the next iteration’s value; it is not ordinary assignment to the current binding.
Use break; to exit the innermost loop and continue; to run the header step
immediately:
func first_multiple(limit : Int, divisor : Int) -> Int do for value = 1; value <= limit; value = value + 1 do if value % divisor == 0 then return value; end; end; -1endExplicit functional loop updates
Section titled “Explicit functional loop updates”When a loop carries several values, omit the header step and use continue
to state the next values together:
func greatest_common_divisor(left : Int, right : Int) -> Int do result : Int = do for a = left, b = right;; do if b == 0 then break result with a; end; continue a = b, b = a % b; end; end; resultendAll update expressions read the old state and are committed simultaneously. That rule makes swaps and multi-value transitions predictable. State variables not named by an explicit update keep their current value.
The labelled do binding carries the final value out of the loop. This is the
same local control-transfer form used by more advanced algorithms; it does not
return from the whole function.
An unconditional loop uses for ;; do ... end. Such a loop must have a
reachable break, return, or other visible exit unless it is intentionally
infinite.
switch belongs with datatypes and patterns, so it is introduced in
Datatypes and basic patterns.
Next: records and tuples.