Added a REMOVE-FROM-PLIST (same as SANS)
[alexandria.git] / binding.lisp
blob8275c496b36ca9509d8556c7b61964b94d1589e1
1 (in-package :alexandria)
3 (defmacro if-let (bindings then-form &optional else-form)
4 "Creates new variable bindings, and conditionally executes either
5 THEN-FORM or ELSE-FORM (defaulting to NIL).
7 BINDINGS must be either single binding of the form:
9 (variable initial-form)
11 or a list of bindings of the form:
13 ((variable-1 initial-form-1)
14 (variable-2 initial-form-2)
15 ...
16 (variable-n initial-form-n))
18 All initial-forms are executed sequentially in the specified order. Then all
19 the variables are bound to the corresponding values.
21 If all variables were bound to true values, the THEN-FORM is executed with the
22 bindings in effect, otherwise the ELSE-FORM is executed with the bindings in
23 effect."
24 (let* ((binding-list (if (and (consp bindings) (symbolp (car bindings)))
25 (list bindings)
26 bindings))
27 (variables (mapcar #'car binding-list)))
28 `(let ,binding-list
29 (if (and ,@variables)
30 ,then-form
31 ,else-form))))
33 (defmacro if-let* (bindings then-form &optional else-form)
34 "Creates new variable bindings, and conditionally executes either THEN-FORM
35 or ELSE-FORM (defaulting to NIL).
37 BINDINGS must be either single binding of the form:
39 (variable initial-form)
41 or a list of bindings of the form:
43 ((variable-1 initial-form-1)
44 (variable-2 initial-form-2)
45 ...
46 (variable-n initial-form-n))
48 Each initial-form is executed in turn, and the variable bound to the
49 corresponding value. Initial-form expressions can refer to variables
50 previously bound by the IF-LET*.
52 If all variables are true after the bindings are complete, the THEN-FORM is
53 executed with the bindings in effect, otherwise the ELSE-FORM is executed with
54 the bindings in effect."
55 (let* ((binding-list (if (and (consp bindings) (symbolp (car bindings)))
56 (list bindings)
57 bindings))
58 (variables (mapcar #'car binding-list)))
59 `(let* ,binding-list
60 (if (and ,@variables)
61 ,then-form
62 ,else-form))))
64 (defmacro when-let (bindings &body forms)
65 "Creates new variable bindings, and conditionally executes FORMS.
67 BINDINGS must be either single binding of the form:
69 (variable initial-form)
71 or a list of bindings of the form:
73 ((variable-1 initial-form-1)
74 (variable-2 initial-form-2)
75 ...
76 (variable-n initial-form-n))
78 All initial-forms are executed sequentially in the specified order. Then all
79 the variables are bound to the corresponding values.
81 If all variables were bound to true values, then FORMS are executed as an
82 implicit PROGN."
83 (let* ((binding-list (if (and (consp bindings) (symbolp (car bindings)))
84 (list bindings)
85 bindings))
86 (variables (mapcar #'car binding-list)))
87 `(let ,binding-list
88 (when (and ,@variables)
89 ,@forms))))
91 (defmacro when-let* (bindings &body forms)
92 "Creates new variable bindings, and conditionally executes either THEN-FORM
93 or ELSE-FORM (defaulting to NIL).
95 BINDINGS must be either single binding of the form:
97 (variable initial-form)
99 or a list of bindings of the form:
101 ((variable-1 initial-form-1)
102 (variable-2 initial-form-2)
104 (variable-n initial-form-n))
106 Each initial-form is executed in turn, and the variable bound to the
107 corresponding value. Initial-form expressions can refer to variables
108 previously bound by the IF-LET*.
110 If all variables are true after the bindings are complete, then FORMS are
111 executed as an implicit PROGN."
112 (let* ((binding-list (if (and (consp bindings) (symbolp (car bindings)))
113 (list bindings)
114 bindings))
115 (variables (mapcar #'car binding-list)))
116 `(let* ,binding-list
117 (when (and ,@variables)
118 ,@forms))))