Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Functions with Parameters

Functions can take parameters and return values. This page covers practical patterns, library integration, and advanced behavior.

Defining a Function

Use #name(params) syntax followed by the function body in braces:

#add(a, b) {
  a + b
}

Calling a Function

result = add(3, 4)
write(result)

Practical Predicate Functions

Functions that return 0 or 1 as boolean results:

#is_even(n) {
  n % 2 == 0
}

#is_odd(n) {
  not is_even(n)
}

write(is_even(42))
write(is_odd(42))

Using Library Functions Inside User Functions

Built-in library functions work inside your user-defined functions:

#random_in_range(min, max) {
  randint@math(min, max)
}

r = random_in_range(5, 10)
write(r)

Bare variable names are auto-dereferenced in library calls:

#rand_name() {
  choice@math("alice", "bob", "charlie")
}

#greet() {
  name = rand_name()
  write("hello", name)
}

greet()
#slugify(s) {
  lower = lower@string(s)
  replace@string(lower, " ", "-")
}

slug = slugify("Hello World")
write(slug)

Return Values

The last expression in the function body is the return value:

#double(x) {
  x * 2
}

write(double(21))

If a function ends with an if expression, the taken branch’s last value is returned:

#sign(n) {
  if n > 0 {
    1
  } orif n < 0 {
    -1
  } else {
    0
  }
}

write(sign(-5))

If there’s no value-producing expression, it returns 0:

#noop() {
  write("no return")
}

x = noop()
write(x)

Variable Save/Restore

When you call a function, lil saves all current variables before running the function body and restores them after. Parameters and any variables changed inside stay contained:

x = "hello"

#test() {
  x = "world"
  write(x)
}

test()
write(x)

Parameters are always save/restored independently of global variables:

x = 100

#f(x) {
  x = x + 1
  write(x)
}

f(5)
write(x)

Recursion

#fib(n) {
  if n <= 2 {
    1
  } else {
    fib(n - 1) + fib(n - 2)
  }
}

write(fib(10))

Notes

Function calls work in both interpreted and compiled (AOT) mode. In compiled mode, each function becomes a standalone C function with its own type inference pass.