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.