Functions
A top-level > name declares a function. Bodies indent under the header; return a value with <<. One-liners collapse the whole body into >> on the same line. Functions live in the global registry — any page, pup, or service can call them.
A multi-line function
main.rat
Indent the body under the header. Locals introduced with << stay scoped to the function; return with a bare <<. Arity is fixed — pass fewer args and the missing slots are null.
> add[a, b]
[sum] << a + b
<< sum
> server
total: add(4, 7) One-liner with >>
Shorthand for "return expr"
> name >> expr is the entire function on one line. Use it for pure computations — no locals, no statements, just the expression. The reactive graph picks up >> definitions the same way derived fields do.
> double[x] >> x * 2
> server
d: double(21) Call from a page
No imports, no registration — just call
Once declared, the function is in scope everywhere. Call it inside [...] like any other expression. Functions can call each other freely — the resolution order is per-file then global, with builtins last.
> add[a, b] >> a + b
> page
<p> 4 + 7 = [add(4, 7)] 4 + 7 = 11
Lambdas
Anonymous functions for collection helpers
Some builtins (filter, map, reduce) take a callback. Pass an inline lambda with fn >> expr — the eval engine threads it back through the same dispatch path your named functions use.
> server
evens: filter([1, 2, 3, 4], fn[n] >> n % 2 == 0) Next: Guards and loops — the (cond) action and [item] in coll forms that drive control flow.