Skip to content
Noodle
InstallLearnPlayground
GitHub

Control flow

Noodle uses structured control flow with explicit delimiters. Conditions must have type Bool; other values are not treated as truthy or falsey.

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"
end
end

Only 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;
end

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;
end

The 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;
-1
end

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;
result
end

All 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.