compile/return
Symbol: compile/return
Syntax: (return VAL ...) – variadic.
Form |
Result |
|---|---|
|
returns |
|
returns |
|
returns a |
|
returns a |
Bare form: the lone symbol return (as in unless ok: return) expands to
(return), so the Python-style spelling returns None from the current
function. The expansion is governed by the
compiler/bare-control-words pragma of the
module being compiled: convert (the default) expands silently, warn expands
with a SyntaxWarning, and error refuses at compile time. Because the bare
symbol always expands, return can never name a variable.
Use-case: Return from the current function and transfer control back to the
caller. return is variadic. With no argument it returns None; with one it
returns that value; with two or more positional arguments it returns a tuple;
and with keyword arguments it returns a multi-value values object.
Behaviour: Compiles each positional argument and emits RETURN N, where N
is the argument count. RETURN 0 returns None, RETURN 1 returns the single
value, and RETURN N (for N > 1) packages the values as a tuple. A keyword
argument re-heads the form as (values ...), so (return a: 1 b: 2) returns a
values object; positional and keyword arguments must not be mixed.
At runtime, when the frame has a parent (e.g. normal CALL), RETURN walks the
dynamic chain with handle(RETURN), runs FINALLY if present, detaches the frame,
and delivers the value to the parent (opcode returns EVAL_CONTROL_RETURNED()
or EVAL_NORMAL()). When the frame has no parent or its parent is the generator
node (KOS_DYN_GEN), RETURN returns EVAL_RETURN(val); eval_event_return
delivers and koskari_eval exits with KOS_RES_RETURN.
Consuming multiple values: index the returned tuple with (item result 0),
or destructure it with var over a pattern or with
let-values:
def swap [a b]:
return b a
var [x y] (swap 1 2) ;; x = 2, y = 1
Examples:
(return) ;; -> None
(return result) ;; -> result
(return a b c) ;; -> #(a b c) (a tuple)
(return a: a b: b c: c) ;; -> values(a=a, b=b, c=c)