Functions
Functions in Do are first-class values. They close over their lexical scope and can be stored in variables, passed as arguments, and returned from other functions.
def
Define named functions with def:
Functions with no arguments must have () after their name:
Implicit Return
A function returns the result of its final statement:
| Statement | Result |
|---|---|
| command | function return value |
let |
value of right-hand side |
bind |
value of scrutinee |
if (with final else) |
result of branch |
if (without final else) |
nil |
try/catch |
result of try (no error) or invoked catch |
All other statements have a nil result.
Explicit Return
Use return for early exit:
Parameters
Positional Parameters
Keyword Parameters
Keyword parameters use key: param syntax in the definition:
Ditto Key Shorthand
The :key shorthand declares a key parameter bound to a variable of the
same name:
The shorthand also works at call sites to pass a variable as a key argument:
let name = Alice
let age = 30
create_user :name :age
# equivalent to: create_user name: $name age: $age
Default Values
Both positional and key parameters support defaults:
def greet name = "World"
echo "Hello, $name!"
greet() # Hello, World!
greet Alice # Hello, Alice!
def connect :host = localhost :port = 8080
echo "Connecting to $host:$port"
connect() # localhost:8080
connect port: 3000 # localhost:3000
connect host: example.com # example.com:8080
Defaults are evaluated on every invocation of the function, so the following
function always returns a fresh empty array if called with no arguments:
Defaults are evaluated left-to-right and may reference earlier parameters:
def window start end = (start + 10)
start..end
assert_eq (window 5) (5..15)
assert_eq (window 5 20) (5..20)
Variadic Parameters
Use ... to accept extra arguments:
The rest parameter receives an immutable argument pack. It is iterable, but
is not itself an iterator, so iterating or spreading it does not consume it.
Iteration yields positional and key arguments in invocation order as key/value
tuples, where the key is the positional argument index (0-origin) for
positional arguments.
def echo_all ...args
for k v = args
echo "$k: $v"
echo_all foo bar: 1 baz
# prints:
# 0: foo
# bar: 1
# 1: baz
Argument Spreading
Spread collections or iterators into a call:
let args = [1, 2, 3]
func ...args
# equivalent to: func 1 2 3
let kwargs = {name: "Alice", age: 30}
func ...kwargs
# equivalent to:
# func name: "Alice" age: 30
Vertical Parameter Layout
Parameters in def can use vertical layout:
do Blocks
Anonymous functions (blocks and lambdas) are created with do:
Statement Context
In statement context, do without a following newline creates a one-statement
block:
With parameters:
If an immediate newline and indented block follows, it creates a multi-statement block:
Expression Context
In expression context, do creates a lambda where the body is an expression:
Non-Local Flow Control
break, continue, and return work through do blocks:
breakexits the innermost enclosing loopcontinueskips to the next iteration of the innermost enclosing loopreturnexits the innermost enclosingdef
This allows natural flow control in callbacks and higher-order functions:
def validate_record record
for field = ["id", "name", "email"]
record.get field else: do
return {valid: false, missing: field}
{valid: true}
A non-local branch will only be effective for the duration of the statement that introduces its containing closure; after this it will propagate a runtime error. The compiler requires that a closure containing non-local branches be in argument position to reduce the likelihood of this sort of error:
# Valid: closure is passed as an argument
def validate record
record.get "name" else: do
return false
true
# Invalid: closure is bound to a variable first
def bad_example()
# Compiler will reject this line
let closure = do return false
record.get "name" else: $closure
Public Functions
Use pub def to export a function from a module:
See Modules for details on the module system.
Decorators
Function defs may be preceded by decorators:
See Decorators for syntax, ordering, and examples.