Let macros
These are macros that combine a let or let* 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)bindings in a let form, then evaluate forms in
a cond.condlet*(bindings &body forms)bindings in a let* form, then evaluate forms in
a cond.iflet(bindings &body (then &optional else))bindings in a let form; if they are all T, execute
the then form. Otherwise, execute the else form.iflet*(bindings &body (then &optional else))bindings in a let* form; if they are all T, execute
the then form. Otherwise, execute the else form.orlet(bindings &body body)body in a progn.(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)body in an implicit progn.unlesslet*(bindings &body body)bindings in a let* form; if they are all not NIL,
evaluate body, which is wrapped in an implicit progn.whenlet(bindings &body body)body in an implicit progn.whenlet*(bindings &body body)bindings in a let* form; if they all evaluate to T,
evaluate body, which is wrapped in an implicit progn.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)path for reading, bound to stream, with any remaining arguments
passed to with-open-file, and execute body.with-write-to-file((stream path &rest args &key (direction output directionp) &allow-other-keys) &body body)body with the file at path opened and bound to the
value of stream. Any remaining keyword arguments are passed to
with-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 to with-open-file.
with-string-output-to-file
((path &rest args &key (direction :output directionp)
&allow-other-keys)
&body body)Evaluate body, and call mkstr on the result. Write the
resulting string to path. Any remaining arguments are sent to
with-open-file.
General
in(obj seq &key (test (function eql)) key deep)Returns T if obj, is in seq.
If seq is a list, test is used to determine whether the object
matches. If key is not NIL, it is applied to elements before
test. If deep is true, seq will be flattened before
checking the list.
If seq is a vector, test is used to determine whether the
object matches. If key is not NIL, it is applied to elements
before test.
If seq is a hash table, test does not apply; the hash table's
test is used. If key is not NIL, it is applied to obj before
looking it up.