Overview
A bytecode-compiled Scheme-like Lisp with symbol interning, lexical addressing,
and tail call optimization. Programs are compiled to a stack-based VM and executed.
If display or newline is called, the accumulated output
is returned; otherwise the result of the last expression is returned.
Data Types
- Integer: 64-bit signed (
i64). Literals: 42, -5
- String: double-quoted with escape sequences (
\n, \t, \\, \")
- Boolean:
#t (true), #f (false)
- List:
(1 2 3); the empty list () is nil
- Nil:
() — the empty list, also the "void" return value
- Symbol: unquoted identifiers like
x, foo-bar
- Lambda: first-class closures
Truthiness: everything is truthy except #f and ().
Syntax
Programs are S-expressions. Function calls use prefix notation:
(f arg1 arg2). Comments begin with ; and extend
to end of line. Quoting: 'expr is shorthand for
(quote expr).
Special Forms
| Form | Syntax | Description |
quote | (quote expr) or 'expr | Return expr unevaluated |
define | (define name expr) | Bind name to value in current environment |
define | (define (f x y) body...) | Function definition sugar |
lambda | (lambda (params) body...) | Create an anonymous function (closure) |
if | (if test then else?) | Conditional; else branch is optional (returns nil) |
and | (and expr...) | Short-circuit AND; returns last truthy or first falsy |
or | (or expr...) | Short-circuit OR; returns first truthy or last falsy |
begin | (begin expr...) | Evaluate expressions in sequence, return last |
let | (let ((x 1) (y 2)) body...) | Local bindings |
set! | (set! name expr) | Mutate an existing binding |
Built-in Functions
Arithmetic (5)
| Function | Syntax | Description |
+ | (+ a b ...) | Sum (variadic, identity 0) |
- | (- a) or (- a b ...) | Negate (unary) or subtract (binary+) |
* | (* a b ...) | Product (variadic, identity 1) |
/ | (/ a b) | Division (error if b=0) |
% | (% a b) | Remainder (aliases: remainder, modulo) |
Comparison (6)
| Function | Syntax | Description |
= | (= a b) | Equality (structural for non-numbers, numeric for numbers) |
< | (< a b) | Less than |
> | (> a b) | Greater than |
<= | (<= a b) | Less than or equal |
>= | (>= a b) | Greater than or equal |
not | (not a) | Logical negation |
List Operations (6)
| Function | Syntax | Description |
car | (car lst) | First element of list |
cdr | (cdr lst) | Rest of list (all but first) |
cons | (cons a lst) | Prepend element to list |
list | (list a b ...) | Create list from arguments |
null? | (null? x) | Is x the empty list? |
pair? | (pair? x) | Is x a pair? |
I/O (3)
| Function | Syntax | Description |
display | (display x) | Print value (strings without quotes); compiled as opcode |
newline | (newline) | Print a newline character; compiled as opcode |
print | (print x ...) | Print values with trailing newline |
Secrets (1)
| Function | Syntax | Description |
env | (env "KEY") | Read a secret by name; returns its string value |
HTTP Outbound (2)
| Function | Syntax | Description |
http-get | (http-get "url") | HTTP GET request; returns response body as string |
http-post | (http-post "url" "body") | HTTP POST request; returns response body as string |
KV Storage (3)
| Function | Syntax | Description |
kv-get | (kv-get "key") | Get value for key; returns empty string if not found |
kv-set | (kv-set "key" "value") | Set key to value; returns empty string |
kv-del | (kv-del "key") | Delete key; returns empty string |
KV storage is only available for saved functions (not ad-hoc /api/run).
Type Predicates (1)
| Function | Syntax | Description |
number? | (number? x) | Is x a number (integer or float)? |
Examples
Factorial
(define (fact n)
(if (<= n 1) 1
(* n (fact (- n 1)))))
(fact 10) ; => 3628800
Tail-recursive sum
(define (sum n acc)
(if (= n 0) acc
(sum (- n 1) (+ acc n))))
(sum 100000 0) ; => 5000050000
Closures
(define (make-adder n)
(lambda (x) (+ n x)))
((make-adder 5) 10) ; => 15
FizzBuzz
(define (fizzbuzz n)
(if (= (% n 15) 0) (display "FizzBuzz")
(if (= (% n 3) 0) (display "Fizz")
(if (= (% n 5) 0) (display "Buzz")
(display n))))
(newline))
(define (loop i)
(if (<= i 20)
(begin (fizzbuzz i) (loop (+ i 1)))))
(loop 1)
Constraints
- Number types:
i64 integers and f64 floats (auto-promoted when mixed)
- Tail call optimization: via dedicated
TailCall opcode in the VM
- Instruction limit (CLI): 10,000,000
- Instruction limit (API): 500,000
- Division by zero is a runtime error