Prelude Macros

Macros loaded automatically before user code. These expand at compile time.

MacroDescription
defn srcLoaded automatically by the Expander before user code expansion. These are defmacro definitions — they register macros in the Expander's macro table and produce no runtime code. defn - function definition shorthand (defn f (x y) body...) => (def f (fn (x y) body...))
let* srclet - alias for let (retained for Scheme familiarity) let is already sequential; let expands to nested single-binding lets
-> src-> thread-first: insert value as first argument (-> val (f a) (g b)) => (g (f val a) b)
->> src->> thread-last: insert value as last argument (->> val (f a) (g b)) => (g b (f a val))
as-> srcas-> - thread with named binding (as-> val var (f var) (g var)) => binds val to var, threads through forms
some-> srcsome-> - thread-first, short-circuiting on nil (some-> val (f a) (g b)) => like -> but stops if any step returns nil
some->> srcsome->> - thread-last, short-circuiting on nil (some->> val (f a) (g b)) => like ->> but stops if any step returns nil
when srcwhen - execute body if test is truthy, return nil otherwise
unless srcunless - execute body if test is falsy, return nil otherwise
default srcdefault - supply a default value for a &named parameter (default x 42) assigns x to 42 only if x is nil (not provided). Unlike (or), this correctly preserves explicitly-passed false values.
yield srcyield - cooperative suspension (yield) => (emit :yield nil) (yield value) => (emit :yield value)
error srcerror - signal a fiber error (error) => (emit :error nil) (error value) => (emit :error value)
try srctry/catch - error handling via fibers Usage: (try body... (catch e handler...)) The last form must be (catch binding handler-body...) Body forms run in a fiber that catches errors. If an error occurs, the catch handler runs with the error bound. If no error occurs, the body result is returned.
protect srcWARNING: protect is synchronous. The body must not perform async I/O (port/open, port/read-line, tcp/connect, etc.). Use protect inside ev/spawn if you need error capture around async work.
defer srcExample: (let [p (port/open "data.txt" :read)] (defer (port/close p) # cleanup: always runs, closes port (port/read-all p))) # body: reads contents, return value
with srcwith - resource management (acquire/release) Usage: (with binding ctor dtor body...) Acquires the resource, runs body, then releases via destructor. Errors in body are propagated after cleanup.
yield* srcyield - delegate to sub-fiber Resumes the sub-fiber, yielding each of its values to the caller. Resume values from the caller are passed through to the sub-fiber. Returns the sub-fiber's final value when it completes.
ffi/defbind srcffi/defbind - convenient FFI function binding Usage: (ffi/defbind name lib-handle "c-name" return-type [arg-types...]) Expands to a wrapper function that looks up the symbol, creates a signature, and defines a function that calls it. Example: (ffi/defbind abs libc "abs" :int [:int]) => (def abs (let [ptr__ (ffi/lookup libc "abs") sig__ (ffi/signature :int [:int])] (fn (a0) (ffi/call ptr__ sig__ a0))))
each srceach - iterate over a sequence Dispatches on type-of: lists use first/rest, indexed types use get/length. (each x coll body...) or (each x in coll body...)
case srccase - equality dispatch (flat pairs) (case expr val1 body1 val2 body2 ... [default]) Uses gensym to avoid double evaluation of the dispatch expression. Odd element count means the last element is the default.
if-let srcif-let - conditional binding (flat pairs) (if-let [x expr ...] then else) Each binding is evaluated and checked for truthiness. If any binding value is falsy, the else branch runs.
when-let srcwhen-let - conditional binding without else (flat pairs) (when-let [x expr ...] body...) Sugar for (if-let bindings (begin body...) nil)
when-ok srcwhen-ok - protect + destructure in one step (when-ok [val (expr)] body...) => runs body with val if expr succeeds Returns nil when expr errors (body is skipped).
forever srcforever - infinite loop (forever body...) Expands to (while true body...) Use (break) or (break value) to exit.
repeat srcrepeat - run body N times (repeat 3 (println "hi")) prints "hi" three times
apply srcapply - call function with args spread from final list argument (apply f args) => (f (splice args)) (apply f a b args) => (f a b (splice args))
ffi/with-stack srcffi/with-stack - scoped FFI stack allocations (ffi/with-stack [[p :int 42] [buf 64]] body...) Each binding is [name type value] for typed scalars or [name size] for raw buffers. Pointers are malloc'd, written, and freed on scope exit.
with-allocator srcwith-allocator - route heap allocations through a custom allocator (with-allocator alloc body...) => installs alloc, runs body in defer, uninstalls Values allocated within the body use the provided allocator. When the form exits, all custom-allocated objects are freed. Do not retain references to these objects beyond the form's dynamic extent.