Add some macros.
* Add a variety of let-based macros to abstract common patterns.
This commit is contained in:
parent
d3b8cb6d26
commit
4cb1950c5f
|
@ -194,6 +194,36 @@ will be returned as an alist:
|
||||||
|
|
||||||
@end(section)
|
@end(section)
|
||||||
|
|
||||||
|
@begin(section)
|
||||||
|
@title(Macros)
|
||||||
|
|
||||||
|
@begin(deflist)
|
||||||
|
|
||||||
|
@term(Let macros)
|
||||||
|
@begin(def)
|
||||||
|
|
||||||
|
These are macros that combine a @c(let) or @c(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.
|
||||||
|
|
||||||
|
@cl:with-package[name="kutils"](
|
||||||
|
@cl:doc(macro condlet)
|
||||||
|
@cl:doc(macro condlet*)
|
||||||
|
@cl:doc(macro iflet)
|
||||||
|
@cl:doc(macro iflet*)
|
||||||
|
@cl:doc(macro unlesslet)
|
||||||
|
@cl:doc(macro unlesslet*)
|
||||||
|
@cl:doc(macro whenlet)
|
||||||
|
@cl:doc(macro whenlet*)
|
||||||
|
)
|
||||||
|
|
||||||
|
@end(def)
|
||||||
|
|
||||||
|
@end(deflist)
|
||||||
|
|
||||||
|
@end(section)
|
||||||
|
|
||||||
@begin(section)
|
@begin(section)
|
||||||
@title(Symbol index)
|
@title(Symbol index)
|
||||||
|
|
||||||
|
@ -220,6 +250,12 @@ described in "Miscellaneous utilities" under "General".)
|
||||||
@item(@c(compose) is a function defined in @c(on.lisp), described in
|
@item(@c(compose) is a function defined in @c(on.lisp), described in
|
||||||
"On Lisp utilities".)
|
"On Lisp utilities".)
|
||||||
|
|
||||||
|
@item(@c(condlet) is a macro defined in @c(macros.lisp), described in
|
||||||
|
"Macros".)
|
||||||
|
|
||||||
|
@item(@c(condlet*) is a macro defined in @c(macros.lisp), described in
|
||||||
|
"Macros".)
|
||||||
|
|
||||||
@item(@c(copy-hash-table) is a function defined in
|
@item(@c(copy-hash-table) is a function defined in
|
||||||
@c(kutils-hash-tables.lisp), described in "Hash-table related
|
@c(kutils-hash-tables.lisp), described in "Hash-table related
|
||||||
utilities".)
|
utilities".)
|
||||||
|
@ -257,6 +293,12 @@ utilities".)
|
||||||
@c(kutils-hash-tables.lisp), described in "Hash-table related
|
@c(kutils-hash-tables.lisp), described in "Hash-table related
|
||||||
utilities".)
|
utilities".)
|
||||||
|
|
||||||
|
@item(@c(iflet) is a macro defined in @c(macros.lisp), described in
|
||||||
|
"Macros".)
|
||||||
|
|
||||||
|
@item(@c(iflet*) is a macro defined in @c(macros.lisp), described in
|
||||||
|
"Macros".)
|
||||||
|
|
||||||
@item(@c(interpose) is a function defined in @c(kutils.lisp),
|
@item(@c(interpose) is a function defined in @c(kutils.lisp),
|
||||||
described in "Miscellaneous utilities" under "Clojure-inspired
|
described in "Miscellaneous utilities" under "Clojure-inspired
|
||||||
functions".)
|
functions".)
|
||||||
|
@ -295,6 +337,18 @@ Lisp utilities".)
|
||||||
@item(@c(take) is a function defined in @c(kutils.lisp), described in
|
@item(@c(take) is a function defined in @c(kutils.lisp), described in
|
||||||
"Miscellaneous utilities" under "Clojure-inspired functions".)
|
"Miscellaneous utilities" under "Clojure-inspired functions".)
|
||||||
|
|
||||||
|
@item(@c(unlesslet) is a macro defined in @c(macros.lisp), described in
|
||||||
|
"Macros".)
|
||||||
|
|
||||||
|
@item(@c(unlesslet*) is a macro defined in @c(macros.lisp), described in
|
||||||
|
"Macros".)
|
||||||
|
|
||||||
|
@item(@c(whenlet) is a macro defined in @c(macros.lisp), described in
|
||||||
|
"Macros".)
|
||||||
|
|
||||||
|
@item(@c(whenlet*) is a macro defined in @c(macros.lisp), described in
|
||||||
|
"Macros".)
|
||||||
|
|
||||||
@item(@c(with-new-hash-table) is a macro defined in
|
@item(@c(with-new-hash-table) is a macro defined in
|
||||||
@c(kutils-hash-tables.lisp), described in "Hash-table related
|
@c(kutils-hash-tables.lisp), described in "Hash-table related
|
||||||
utilities".)
|
utilities".)
|
||||||
|
@ -318,6 +372,8 @@ Alphabetical documentation for all exported symbols.
|
||||||
@cl:doc(function build-vector)
|
@cl:doc(function build-vector)
|
||||||
@cl:doc(function cartprod2)
|
@cl:doc(function cartprod2)
|
||||||
@cl:doc(function compose)
|
@cl:doc(function compose)
|
||||||
|
@cl:doc(macro condlet)
|
||||||
|
@cl:doc(macro condlet*)
|
||||||
@cl:doc(function copy-hash-table)
|
@cl:doc(function copy-hash-table)
|
||||||
@cl:doc(macro defmacro!)
|
@cl:doc(macro defmacro!)
|
||||||
@cl:doc(function drop)
|
@cl:doc(function drop)
|
||||||
|
@ -329,6 +385,8 @@ Alphabetical documentation for all exported symbols.
|
||||||
@cl:doc(function group)
|
@cl:doc(function group)
|
||||||
@cl:doc(function hash-table-to-alist)
|
@cl:doc(function hash-table-to-alist)
|
||||||
@cl:doc(function hashkeys)
|
@cl:doc(function hashkeys)
|
||||||
|
@cl:doc(macro iflet)
|
||||||
|
@cl:doc(macro iflet*)
|
||||||
@cl:doc(function interpose)
|
@cl:doc(function interpose)
|
||||||
@cl:doc(function macroexpand-n)
|
@cl:doc(function macroexpand-n)
|
||||||
@cl:doc(macro mapv)
|
@cl:doc(macro mapv)
|
||||||
|
@ -341,6 +399,10 @@ Alphabetical documentation for all exported symbols.
|
||||||
@cl:doc(macro sethash)
|
@cl:doc(macro sethash)
|
||||||
@cl:doc(function symb)
|
@cl:doc(function symb)
|
||||||
@cl:doc(function take)
|
@cl:doc(function take)
|
||||||
|
@cl:doc(macro unlesslet)
|
||||||
|
@cl:doc(macro unlesslet*)
|
||||||
|
@cl:doc(macro whenlet)
|
||||||
|
@cl:doc(macro whenlet*)
|
||||||
@cl:doc(macro with-new-hash-table)
|
@cl:doc(macro with-new-hash-table)
|
||||||
@cl:doc(function zip))
|
@cl:doc(function zip))
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
;;;; macros.lisp
|
||||||
|
|
||||||
|
(in-package #:kutils)
|
||||||
|
|
||||||
|
;;; Various utility macros.
|
||||||
|
|
||||||
|
(defmacro when (bindings &body body)
|
||||||
|
"Evaluate the bindings in a let form; if they all evaluate to T,
|
||||||
|
evaluate @c(body) in an implicit @c(progn)."
|
||||||
|
(let ((bindings (if (listp (first bindings)) bindings (list bindings))))
|
||||||
|
`(let (,@bindings)
|
||||||
|
(when (and ,@(mapcar #'first bindings))
|
||||||
|
,@body))))
|
||||||
|
|
||||||
|
(defmacro whenlet* (bindings &body body)
|
||||||
|
"Evaluate @c(bindings) in a @c(let*) form; if they all evaluate to T,
|
||||||
|
evaluate @c(body), which is wrapped in an implicit @c(progn)."
|
||||||
|
(let ((bindings (if (listp (first bindings)) bindings (list bindings))))
|
||||||
|
`(let* (,@bindings)
|
||||||
|
(when (and ,@(mapcar #'first bindings))
|
||||||
|
,@body))))
|
||||||
|
|
||||||
|
(defmacro unlesslet (bindings &body body)
|
||||||
|
"Evaluate the bindings in a let form; if they don't all evaluate to T,
|
||||||
|
evaluate @c(body) in an implicit @c(progn)."
|
||||||
|
(let ((bindings (if (listp (first bindings)) bindings (list bindings))))
|
||||||
|
`(let (,@bindings)
|
||||||
|
(unless (and ,@(mapcar #'first bindings))
|
||||||
|
,@body))))
|
||||||
|
|
||||||
|
(defmacro unlesslet* (bindings &body body)
|
||||||
|
"Evaluate @c(bindings) in a @c(let*) form; if they are all not NIL,
|
||||||
|
evaluate @c(body), which is wrapped in an implicit @c(progn)."
|
||||||
|
(let ((bindings (if (listp (first bindings)) bindings (list bindings))))
|
||||||
|
`(let* (,@bindings)
|
||||||
|
(unless (and ,@(mapcar #'first bindings))
|
||||||
|
,@body))))
|
||||||
|
|
||||||
|
(defmacro iflet (bindings &body (then &optional else))
|
||||||
|
"Evaluate @c(bindings) in a @c(let) form; if they are all T, execute
|
||||||
|
the @c(then) form. Otherwise, execute the @c(else) form."
|
||||||
|
(let ((bindings (if (listp (first bindings)) bindings (list bindings))))
|
||||||
|
`(let* (,@bindings)
|
||||||
|
(if (and ,@(mapcar #'first bindings))
|
||||||
|
(progn ,then)
|
||||||
|
(progn ,else)))))
|
||||||
|
|
||||||
|
(defmacro iflet* (bindings &body (then &optional else))
|
||||||
|
"Evaluate @c(bindings) in a @c(let*) form; if they are all T, execute
|
||||||
|
the @c(then) form. Otherwise, execute the @c(else) form."
|
||||||
|
(let ((bindings (if (listp (first bindings)) bindings (list bindings))))
|
||||||
|
`(let* (,@bindings)
|
||||||
|
(if (and ,@(mapcar #'first bindings))
|
||||||
|
(progn ,then)
|
||||||
|
(progn ,else)))))
|
||||||
|
|
||||||
|
(defmacro condlet (bindings &body forms)
|
||||||
|
"Evaluate @c(bindings) in a @c(let) form, then evaluate @c(forms) in
|
||||||
|
a @c(cond)."
|
||||||
|
(let ((bindings (if (listp (first bindings)) bindings (list bindings))))
|
||||||
|
`(let (,@bindings)
|
||||||
|
(cond ,@forms))))
|
||||||
|
|
||||||
|
(defmacro condlet* (bindings &body forms)
|
||||||
|
"Evaluate @c(bindings) in a @c(let*) form, then evaluate @c(forms) in
|
||||||
|
a @c(cond)."
|
||||||
|
(let ((bindings (if (listp (first bindings)) bindings (list bindings))))
|
||||||
|
`(let (,@bindings)
|
||||||
|
(cond ,@forms))))
|
||||||
|
|
10
package.lisp
10
package.lisp
|
@ -40,4 +40,14 @@
|
||||||
#:copy-hash-table
|
#:copy-hash-table
|
||||||
#:hash-table-to-alist
|
#:hash-table-to-alist
|
||||||
#:alist-to-hash-table
|
#:alist-to-hash-table
|
||||||
|
|
||||||
|
;; macros.lisp
|
||||||
|
#:whenlet
|
||||||
|
#:whenlet*
|
||||||
|
#:unlesslet
|
||||||
|
#:unlesslet*
|
||||||
|
#:iflet
|
||||||
|
#:iflet*
|
||||||
|
#:condlet
|
||||||
|
#:condlet*
|
||||||
))
|
))
|
||||||
|
|
Loading…
Reference in New Issue