compile/labels
Syntax: (labels [[NAME FORMALS BODY ...] ...] FORM ...)
Behaviour: Like flet, but the bound names are visible to
one another, so the functions can be mutually recursive. Each declaration is
bound with var inside a shared (empty) let scope, so a sibling
reference resolves there before the body runs:
(labels [[even? [n] (if (== n 0) True (odd? (- n 1)))]
[odd? [n] (if (== n 0) False (even? (- n 1)))]]
(even? 10))
is equivalent to:
(let []
(var even? (function even? [n] (if (== n 0) True (odd? (- n 1)))))
(var odd? (function odd? [n] (if (== n 0) False (even? (- n 1)))))
(even? 10))
A binding may call any sibling, including one declared later in the same
labels form.
As with any local binding, a labels binding whose name is also a macro
(a special form, or one of the cad*r accessor macros) does not take effect
in call position – macros expand before names resolve, so they always win. Names
bound to runtime functions are shadowed normally.