- Let macros
These are macros that combine a
let
orlet*
form with a test based on the results of the bindings. This is useful for reducing common boilerplate where a let is used to perform some operations, and some code should be executed based on the results of those bindings.For example, from
kmop/kmop.lisp
:* (macroexpand-1 '(whenlet ((kwarg (slot-initarg slot)) (value (dispatch-get-value slot (slot-table-value slot ht snake-case)))) (list kwarg value))) (LET ((KWARG (SLOT-INITARG SLOT)) (VALUE (DISPATCH-GET-VALUE SLOT (SLOT-TABLE-VALUE SLOT HT SNAKE-CASE)))) (WHEN (AND KWARG VALUE) (LIST KWARG VALUE)))
condlet
(bindings &body forms)
Evaluatebindings
in alet
form, then evaluateforms
in acond
.condlet*
(bindings &body forms)
Evaluatebindings
in alet*
form, then evaluateforms
in acond
.iflet
(bindings &body (then &optional else))
Evaluatebindings
in alet
form; if they are all T, execute thethen
form. Otherwise, execute theelse
form.iflet*
(bindings &body (then &optional else))
Evaluatebindings
in alet*
form; if they are all T, execute thethen
form. Otherwise, execute theelse
form.orlet
(bindings &body body)
For each set of bindings, evaluate them in sequence. If each binding evaluates to T, evaluatebody
in aprogn
.(macroexpand-1 '(orlet ((cls (class-symbol s)) (slots (only-key-slots cls)) (args (json-slots tbl slots))) (apply #'make-instance cls args))) (LET ((CLD (CLASS-SYMBOL S))) (WHEN CLS (LET ((SLOTS (ONLY-KEY-SLOTS CLS))) (WHEN SLOTS (LET ((ARGS (JSON-SLOTS TBL SLOTS))) (WHEN ARGS (PROGN (APPLY #'MAKE-INSTANCE CLS ARGS))))))))
unlesslet
(bindings &body body)
Evaluate the bindings in a let form; if they don't all evaluate to T, evaluatebody
in an implicitprogn
.unlesslet*
(bindings &body body)
Evaluatebindings
in alet*
form; if they are all not NIL, evaluatebody
, which is wrapped in an implicitprogn
.whenlet
(bindings &body body)
Evaluate the bindings in a let form; if they all evaluate to T, evaluatebody
in an implicitprogn
.whenlet*
(bindings &body body)
Evaluatebindings
in alet*
form; if they all evaluate to T, evaluatebody
, which is wrapped in an implicitprogn
.- File macros
These macros abstract common operations on files.
with-read-from-file
((stream path &rest args &key (direction input directionp) &allow-other-keys) &body body)
Openpath
for reading, bound tostream
, with any remaining arguments passed towith-open-file
, and executebody
.with-write-to-file
((stream path &rest args &key (direction output directionp) &allow-other-keys) &body body)
Evaluatebody
with the file atpath
opened and bound to the value ofstream
. Any remaining keyword arguments are passed towith-open-file
.The following two macros aren't yet able to be documented with Codex, as they are defined using the
defmacro!
macro:read-file-as-string (path &rest args &key (direction nil directionp) &allow-other-keys)
Read the contents of the file at
path
as a string. Any remaining arguments are sent towith-open-file
.with-string-output-to-file ((path &rest args &key (direction :output directionp) &allow-other-keys) &body body)
Evaluate
body
, and callmkstr
on the result. Write the resulting string topath
. Any remaining arguments are sent towith-open-file
.- General
-
in
(obj seq &key (test (function eql)) key deep)
Returns T if
obj
, is inseq
.If
seq
is a list,test
is used to determine whether the object matches. Ifkey
is not NIL, it is applied to elements beforetest
. Ifdeep
is true,seq
will be flattened before checking the list.If
seq
is a vector,test
is used to determine whether the object matches. Ifkey
is not NIL, it is applied to elements beforetest
.If
seq
is a hash table,test
does not apply; the hash table's test is used. Ifkey
is not NIL, it is applied toobj
before looking it up.