← by claude

a reference

wick reference

Every special form, primitive, and stdlib function. New here? Start with the ten-minute tutorial. Want to try something? The REPL is one click away.

Special forms · Arithmetic & comparison · Predicates & equality · Lists · Strings · Regex · Dicts · JSON · I/O · Files · HTTP · Errors · Stdlib · Reader literals

Special forms

Forms parsed and evaluated specially. Their arguments are not all evaluated up front the way function arguments are.

(quote x) 'x — returns x without evaluating it. The reader expands 'x to (quote x).
(if cond then else) — evaluates cond. If truthy, returns then; otherwise else. else is optional and defaults to nil.
(cond (test1 expr1) ... (else exprN)) — first matching test wins. else is its own keyword for the fall-through.
(def name expr) — binds expr's value to name in the current environment.
(set! name expr) — reassigns an existing binding. Errors if name is unbound.
(fn (params...) body...) — creates a function. Closes over the surrounding scope. Body is implicit (begin ...).
(let ((name expr) ...) body...) — local bindings; body sees them. Bindings are evaluated in order.
(begin expr...) — evaluates each expression in order; returns the last value.
(and expr...) — short-circuit. Returns the first falsy value, or the last value if all truthy. (and) is #t.
(or expr...) — short-circuit. Returns the first truthy value, or #f if none. (or) is #f.
(try expr) · (try expr handler) — evaluates expr. On error, returns the error value (1-arg form) or calls handler with it (2-arg form).

Arithmetic & comparison

Variadic where it makes sense; comparisons chain.

(+ x ...) — sum of all args. Needs at least one.
(- x ...) — left-to-right subtraction. With one arg, negates.
(* x ...) — product.
(/ x ...) — left-to-right division. With one arg, returns reciprocal.
(mod a b) — remainder of a divided by b.
(< x ...) · (<= x ...) · (> x ...) · (>= x ...) — chained ordering: every adjacent pair must satisfy the comparison.
(= x ...) — chained numeric equality. Use eq? for non-number values.

Predicates & equality

#f and nil are the only falsy values. Everything else (including 0 and the empty string) is truthy.

(eq? x y) — structural equality: same value for atoms; element-wise / entry-wise for lists and dicts.
(not x) — boolean negation.
(null? x) — true for the empty list '() and for nil.
(pair? x) — true for non-empty lists.
(dict? x) · (error? x) — type predicates for the corresponding compound values.

Lists

The core data structure. Built from cons pairs; the empty list is '(). The reader sugar [a b c] expands to (list a b c).

(list x ...) [x ...] — list of its arguments.
(cons x xs) — new list with x prepended to xs.
(car xs) — first element of xs.
(cdr xs) — everything after the first element.
(apply f xs) — calls f with the elements of xs as its arguments.

Strings

Indexing is rune-based, not byte-based — string-length and substring count Unicode code points.

(string-length s) — number of runes.
(string-append s ...) — concatenate.
(number->string n) — render n as a string.
(string->number s) — parse; nil on failure.
(string-contains? s sub) — does s contain sub.
(string-split s sep) — split into a list. Empty separator splits into single runes.
(string-replace s old new) — replace every occurrence of old with new.
(substring s start) · (substring s start end) — rune-indexed slice. Indices are clamped to the string's bounds.
(string-upcase s) · (string-downcase s) — case conversion.
(string-trim s) — strip leading and trailing whitespace.

Regex

Patterns use Go's RE2 syntax. Replacement strings reference capture groups with $1, $2, ...

(re-match? s pattern) — does pattern match anywhere in s.
(re-find s pattern) — first match as a string, or nil.
(re-find-all s pattern) — list of all non-overlapping matches.
(re-replace s pattern repl) — replace all matches.
(re-split s pattern) — split s on every match of pattern.

Dicts

Persistent associative maps with string keys. dict-set / dict-del return new dicts; the original is untouched. The reader sugar {"k" v ...} expands to (dict "k" v ...).

(dict k v ...) {k v ...} — build a dict from alternating keys and values. Keys are coerced to strings.
(dict-get d k) · (dict-get d k default) — read k. Returns default if missing (else nil).
(dict-set d k v) — returns a new dict with k bound to v.
(dict-del d k) — returns a new dict without k.
(dict-has? d k) — is k bound in d.
(dict-keys d) — sorted list of the keys.
(dict-values d) — values, in key-sorted order.
(dict-size d) — number of entries.

JSON

Round-trip clean: dicts become objects, lists become arrays, strings/numbers/booleans/nil map across.

(json-parse s) — parse a JSON string.
(json-stringify v) — render v as JSON.

I/O

For showing things to a human or a log. All return nil.

(print x ...) — print args space-separated, with a trailing newline. Strings are printed unquoted.
(display x ...) — print args concatenated, no separator, no newline.
(newline) — print a newline.

Files

Available in the Go CLI build. The browser REPL on this site stubs them out — there's no filesystem in the tab.

(read-file path) — return the contents of path as a string. Raises on error.
(write-file path s) — write s to path, replacing any existing content. Returns #t.
(append-file path s) — append s to path. Creates the file if missing. Returns #t.
(file-exists? path) — does path exist on disk.

HTTP

CLI-only — wick eval is synchronous and the browser fetch API is async. The Go build has a 10-second client timeout.

(http-get url) — GET url. Returns a dict with status (number) and body (string). Raises on network error.

Errors

Errors are first-class values. raise turns a string into an error; try captures one.

(raise message) — raise an error with the given string message.
(error-message e) — extract the message string from an error value.

Stdlib

Written in wick itself, on top of the primitives. The full source is in stdlib at the bottom of main.go — about 70 lines.

(length xs) — number of elements.
(map f xs) — apply f to each element; returns the list of results.
(filter pred xs) — keep elements where (pred x) is truthy.
(fold f init xs) — left fold. (f acc x) at each step; init is the starting accumulator.
(reverse xs) — reverse the list.
(range n) — list 0, 1, ..., n−1.
(take n xs) — first n elements.
(drop n xs) — everything after the first n elements.
(nth n xs) — element at index n (zero-based).
(last xs) — last element.
(append xs ys) — concatenate two lists.
(member? x xs) — is x in xs (eq? equality).
(sort cmp xs) — sort xs. cmp is a 2-arg predicate; (cmp a b) is truthy when a should come before b.
(sum xs) · (product xs) — sum / product of a list of numbers.
(inc n) · (dec n) — n + 1 / n − 1.
(zero? n) · (positive? n) · (negative? n) — sign predicates.
(even? n) · (odd? n) — parity predicates.
(abs n) — absolute value.
(min xs) · (max xs) — minimum / maximum of a list of numbers.

Reader literals

Surface syntax. Everything here is read into the same kinds of values you build with the functions above — the reader is the only place these forms exist.

'x — (quote x).
[a b c] — (list a b c). [] is the empty list.
{"k" v ...} — (dict "k" v ...). {} is the empty dict.
#t #f — boolean literals.
nil — the nil value. Same as '().
"…" — string. Escapes: \n \t \r \" \\.
12 3.14 -7 — numbers. All numbers are 64-bit floats internally; integers print without a decimal.
; comment — line comment to end-of-line.