control flow

Decisions & failure

if, for each, while, repeat — and the but-if failure model that makes Vision safe to read.

Decisions

if branches on a condition. Add further conditions with or if. The final fallthrough is otherwise. All three are optional — you can have a bare if with no otherwise.

if the score is at least 90
    say "excellent"
or if the score is at least 70
    say "good"
otherwise
    say "keep going"

Loops

Three repetition forms, each for a different situation:

for each name in the names
    say name

while the queue is not empty
    the item is the first value in the queue
    process the item

repeat 5 times
    say "tick"

for each iterates a collection — use it when you have items and want to visit each one. while runs while a condition holds — use it when the number of iterations is not known up front. repeat n times runs a fixed count — use it when the number is known and doesn't change.

Failure: the but if model

Vision has no exceptions and no silent failures. Every operation that can fail must be immediately followed by one or more but if clauses. The compiler refuses to build a program where a failure is unhandled.

read the file at the path giving the contents
    but if it isn't there, say "file missing" and stop
    but if it can't be read, explain why and hand it on

write the result to the file at the output path
    but if it can't be written, give up

Each but if names the failure condition in plain language (it isn't there, it can't be read) and provides a resolution. The conditions are defined by the operation — read the docs for each operation to know what can fail.

Resolutions

A but if clause must end with one of three resolutions:

  • stop — the failure is handled here. This path ends. The program or enclosing verb continues normally after the block.
  • hand it on — the failure is passed to the caller. The current verb ends. The caller must also handle it with but if.
  • give up — fatal exit. The entire program ends. Use only when there is genuinely no way to continue.
to load the config, given the path:
    read the file at the path giving the bytes
        but if it isn't there, hand it on
        but if it can't be read, hand it on
    answer the bytes

Absence

A value that might not exist is typed as maybe — it either holds a value or holds nothing. Check for it with if there is before using it. The compiler prevents you from using a maybe-value without checking.

if there is the result
    say the result
otherwise
    say "no result yet"