tur/macros
core control-flow and utility macros (cond, when, for, do-m, ...).
Since: Phase M7
cond
(cond [& clauses])
variadic conditional branching via nested if chains.
| & clauses -- alternating test/expression pairs, with optional :else at end |
The expression corresponding to the first truthy test, or the :else expression if present, or nil if no clause matches.
(cond (> x 0) :pos (< x 0) :neg :else :zero) ; => :pos/:neg/:zero
Since: Phase 7
when
(when [test body])
evaluate body only if test is truthy.
| test | the condition to evaluate | |
| body | expression to evaluate when test is truthy |
The value of body if test is truthy, otherwise nil.
(when (> x 0) (print "positive")) ; => prints if x > 0
Since: Phase 7
unless
(unless [test body])
evaluate body only if test is falsy.
| test | the condition to evaluate | |
| body | expression to evaluate when test is falsy |
The value of body if test is falsy, otherwise nil.
(unless (= x 0) (/ 1 x)) ; => evaluates only when x is non-zero
Since: Phase 7
must!
(must! [expr])
unwrap an option or result value, panicking if absent.
| expr | an option or result expression to unwrap |
The unwrapped inner value.
(must! (option-some 42)) ; => 42
Since: Phase R4
must-msg!
(must-msg! [expr msg])
unwrap an option or result value with a custom panic message.
| expr | an option or result expression to unwrap | |
| msg | the message to panic with if the value is absent |
The unwrapped inner value.
(must-msg! (option-some 42) "expected a value") ; => 42
Since: Phase R4
ignore!
(ignore! [expr])
explicitly discard a result value.
| expr | the expression whose value should be discarded |
nil
(ignore! (some-fn-with-result)) ; => nil
Since: Phase R6
do-m
(do-m [& forms])
monadic do-notation using .bind dispatch.
| & forms -- alternating variable/monadic-action pairs followed by a body; | ||
| the last form is the body expression |
A nested .bind chain that threads variable bindings through monadic actions, ending with the body expression.
(do-m x (option-some 5) y (option-some 3) (option-some (+ x y))) ; => (.bind (option-some 5) (fn [x] (.bind (option-some 3) (fn [y] (option-some (+ x y))))))
Since: Phase HKT H6
for
(for [binding-vec & body])
monadic comprehension with optional guards.
| binding-vec | flat vector of alternating var/collection pairs, | |
| with optional :when guard clauses interspersed | ||
| & body -- the body expression(s) to lift into the monad |
A nested .bind/.pure chain that iterates over the collections, filters via :when guards, and lifts the body into the monad.
(for [x coll] (* x 2)) ; => (.bind coll (fn [x] (.pure (* x 2)))) (for [x coll :when (> x 0) y other] (+ x y)) ; => (.bind coll (fn [x] (if (> x 0) (.bind other (fn [y] (.pure (+ x y)))) (.empty x))))
Since: Phase HKT H7
curry
(curry [f])
convert a 2-argument function to its curried form.
| f | a 2-argument function |
A 1-argument function that, given its first argument, returns a 1-argument function that applies f to both.
(defn add [a b] :int (+ a b))
(let [add1 ((curry add) 1)]
(add1 41)) ; => 42
Since: CY3
doc
(doc [name])
print documentation for a function, macro, or struct at the REPL.
| name | symbol whose documentation to display |
Prints the doc string to stdout; returns nil.
(doc cons) ; prints: cons -- prepend a value to a list. ... (doc when) ; prints: when -- evaluate body only if test is truthy. ...
Since: Phase D1 (auto-docs)
with-resource
(with-resource [binding & body])
bind and safely consume a resource within a scope.
| binding | a two-element vector [name init] where init produces the resource | |
| & body -- expressions forming the scope in which the resource is available |
The value of the last body expression.
;; Under -Xsubstructural, r is inferred as linear (must be consumed):
(with-resource [r (ref 42)]
(println @r)
(drop! r))
;; With explicit ^linear annotation:
(with-resource [^linear fh (open-file "data.txt")]
(close-file fh))
Since: ST3
must-use
(must-use [expr])
wrap a value to enforce that it is used at least once.
| expr | the expression whose value must be used |
The value of expr, annotated as ^relevant (must-use under -Xsubstructural).
;; Under -Xsubstructural, the result must be observed before scope exit:
(let [r (must-use (acquire-resource))]
(process r)
(process r)) ; OK -- ^relevant allows duplication
;; Dropping without use is an error:
(let [r (must-use (acquire-resource))]
0) ; ERROR TUR-E0151: relevant value dropped without use
Since: ST3
as->
(as-> [expr name & forms])
thread a value through a pipeline of transformations, naming it at each step.
| expr | the initial value | |
| name | the symbol to bind to the threaded value | |
| & forms -- alternating transformation/name pairs; the last form is the final expression |
The result of the final expression after threading through all transformations.
(as-> 42 x
(* x 2) y
(+ y 10)) ; => 94
Since: Phase M8
derive-show-rest__
(derive-show-rest__ [& fields])
internal helper; generates trailing str-concat chain for derive-show.
derive-show-body__
(derive-show-body__ [TypeName & fields])
internal helper; generates the full show body expression for derive-show.
derive-show
(derive-show [TypeName & fields])
generate a Show instance for a struct.
| TypeName | the struct type name (symbol) | |
| fields | bare symbols or [label accessor] pairs; each bare symbol x | |
| uses label "x" and accessor (.x struct); each [label .accessor] | ||
| pair uses the given label string and accessor symbol. |
A definstance Show form for TypeName.
(derive-show Point x y)
; (show (make-struct Point 3 4)) => "Point { x = 3, y = 4 }"
(derive-show MyStruct name [alias .internal])
; uses (.name s) as "name", (.internal s) as "alias"
Since: SI2
derive-debug-rest__
(derive-debug-rest__ [& fields])
internal helper; generates trailing str-concat chain for derive-debug.
derive-debug-body__
(derive-debug-body__ [TypeName & fields])
internal helper; generates the full debug body expression for derive-debug.
derive-debug
(derive-debug [TypeName & fields])
generate a Debug instance for a struct.
| TypeName | the struct type name (symbol) | |
| fields | bare symbols or [label accessor] pairs (same syntax as derive-show) |
A definstance Debug form for TypeName.
(derive-debug Point x y) ; (debug (make-struct Point 3 4)) => "(Point (x 3) (y 4))"
Since: SI3
derive-display-rest__
(derive-display-rest__ [& fields])
internal helper; generates trailing str-concat chain for derive-display.
derive-display-body__
(derive-display-body__ [TypeName & fields])
internal helper; generates the full display body expression for derive-display.
derive-display
(derive-display [TypeName & fields])
generate a Display instance for a struct.
| TypeName | the struct type name (symbol) | |
| fields | bare symbols or [label accessor] pairs (same syntax as derive-show) |
A definstance Display form for TypeName.
(derive-display Point x y)
; (display (make-struct Point 3 4)) => "Point { x = 3, y = 4 }"
Since: SI3
Internal definitions
dot-- transform (. thing method args...) into (.method thing args...).