90 lines
2.9 KiB
Common Lisp
90 lines
2.9 KiB
Common Lisp
(in-package :alexandria)
|
|
|
|
(defmacro if-let (bindings &body (then-form &optional else-form))
|
|
"Creates new variable bindings, and conditionally executes either
|
|
THEN-FORM or ELSE-FORM. ELSE-FORM defaults to NIL.
|
|
|
|
BINDINGS must be either single binding of the form:
|
|
|
|
(variable initial-form)
|
|
|
|
or a list of bindings of the form:
|
|
|
|
((variable-1 initial-form-1)
|
|
(variable-2 initial-form-2)
|
|
...
|
|
(variable-n initial-form-n))
|
|
|
|
All initial-forms are executed sequentially in the specified order. Then all
|
|
the variables are bound to the corresponding values.
|
|
|
|
If all variables were bound to true values, the THEN-FORM is executed with the
|
|
bindings in effect, otherwise the ELSE-FORM is executed with the bindings in
|
|
effect."
|
|
(let* ((binding-list (if (and (consp bindings) (symbolp (car bindings)))
|
|
(list bindings)
|
|
bindings))
|
|
(variables (mapcar #'car binding-list)))
|
|
`(let ,binding-list
|
|
(if (and ,@variables)
|
|
,then-form
|
|
,else-form))))
|
|
|
|
(defmacro when-let (bindings &body forms)
|
|
"Creates new variable bindings, and conditionally executes FORMS.
|
|
|
|
BINDINGS must be either single binding of the form:
|
|
|
|
(variable initial-form)
|
|
|
|
or a list of bindings of the form:
|
|
|
|
((variable-1 initial-form-1)
|
|
(variable-2 initial-form-2)
|
|
...
|
|
(variable-n initial-form-n))
|
|
|
|
All initial-forms are executed sequentially in the specified order. Then all
|
|
the variables are bound to the corresponding values.
|
|
|
|
If all variables were bound to true values, then FORMS are executed as an
|
|
implicit PROGN."
|
|
(let* ((binding-list (if (and (consp bindings) (symbolp (car bindings)))
|
|
(list bindings)
|
|
bindings))
|
|
(variables (mapcar #'car binding-list)))
|
|
`(let ,binding-list
|
|
(when (and ,@variables)
|
|
,@forms))))
|
|
|
|
(defmacro when-let* (bindings &body body)
|
|
"Creates new variable bindings, and conditionally executes BODY.
|
|
|
|
BINDINGS must be either single binding of the form:
|
|
|
|
(variable initial-form)
|
|
|
|
or a list of bindings of the form:
|
|
|
|
((variable-1 initial-form-1)
|
|
(variable-2 initial-form-2)
|
|
...
|
|
(variable-n initial-form-n))
|
|
|
|
Each INITIAL-FORM is executed in turn, and the variable bound to the
|
|
corresponding value. INITIAL-FORM expressions can refer to variables
|
|
previously bound by the WHEN-LET*.
|
|
|
|
Execution of WHEN-LET* stops immediately if any INITIAL-FORM evaluates to NIL.
|
|
If all INITIAL-FORMs evaluate to true, then BODY is executed as an implicit
|
|
PROGN."
|
|
(let ((binding-list (if (and (consp bindings) (symbolp (car bindings)))
|
|
(list bindings)
|
|
bindings)))
|
|
(labels ((bind (bindings body)
|
|
(if bindings
|
|
`(let (,(car bindings))
|
|
(when ,(caar bindings)
|
|
,(bind (cdr bindings) body)))
|
|
`(progn ,@body))))
|
|
(bind binding-list body))))
|