Add with-gensyms and in macros.

This commit is contained in:
Kyle 2015-09-02 00:12:42 -07:00
parent 6aab1b6bd1
commit 5847a6b054
4 changed files with 54 additions and 2 deletions

View File

@ -87,6 +87,7 @@ some functions I found useful.)
@cl:doc(function group)
@cl:doc(function flatten)
@cl:doc(function compose)
@cl:doc(macro with-gensyms)
)
@ -263,10 +264,13 @@ Evaluate @c(body), and call @c(mkstr) on the result. Write the
resulting string to @c(path). Any remaining arguments are sent to
@c(with-open-file).
@end(def)
@term(General)
@cl:with-package[name="kutils"](
@cl:doc(macro in))
@end(deflist)
@end(section)
@ -373,6 +377,9 @@ utilities".)
@item(@c(iflet*) is a macro defined in @c(macros.lisp), described in
"Macros" under "Let macros".)
@item(@c(in) is a macro defined in @c(macros.lisp), described in
"Macros" under "General".)
@item(@c(interpose) is a function defined in @c(kutils.lisp),
described in "Miscellaneous utilities" under "Clojure-inspired
functions".)
@ -433,6 +440,9 @@ Lisp utilities".)
@item(@c(whenlet*) is a macro defined in @c(macros.lisp), described in
"Macros" under "Let macros".)
@item(@c(with-gensyms) is a macro defined in @c(on.lisp), described in
"On Lisp utilities".)
@item(@c(with-new-hash-table) is a macro defined in
@c(kutils-hash-tables.lisp), described in "Hash-table related
utilities".)
@ -480,6 +490,7 @@ Alphabetical documentation for all exported symbols.
@cl:doc(function hashkeys)
@cl:doc(macro iflet)
@cl:doc(macro iflet*)
@cl:doc(macro in)
@cl:doc(function interpose)
@cl:doc(function macroexpand-n)
@cl:doc(macro mapv)
@ -497,6 +508,7 @@ Alphabetical documentation for all exported symbols.
@cl:doc(macro unlesslet*)
@cl:doc(macro whenlet)
@cl:doc(macro whenlet*)
@cl:doc(macro with-gensyms)
@cl:doc(macro with-new-hash-table)
@cl:doc(macro with-read-from-file)
@cl:doc(macro with-write-to-file)

View File

@ -113,3 +113,32 @@ value of @c(stream). Any remaining keyword arguments are passed to
(error "Specifying :direction is not allowed with WRITE-FILE."))
`(with-open-file (,stream ,path :direction ,direction ,@args)
,@body))
(defun is (a b test key)
"Are a and b equal? If not NIL, #'key is applied to b, then #'test
is called on both."
(declare (inline))
(funcall test
(if key
(funcall key b)
b)
a))
(defmacro in (obj seq &key (test #'eql) key deep)
"Returns T if @c(obj), which may be a vector or list), is in
@c(seq); using @c(test) to determine whether the object matches. If
@c(key) is not NIL, it is applied to the key before @c(test). If
@c(deep) is true, @c(seq) will be flattened before checking the
list. Note that @c(deep) is only valid for lists, and will not behave
as expected with vectors."
(with-gensyms (obj% seq% x!)
(declare (dynamic-extent obj% seq% x!))
`(let ((,obj% ,obj)
(,seq% (if ,deep ,(flatten seq) ,seq)))
(cond
((vectorp ,seq%)
(loop for ,x! across ,seq%
thereis (is ,obj% ,x! ,test ,key)))
((listp ,seq%)
(loop for ,x! in ,seq%
thereis (is ,obj% ,x! ,test ,key)))))))

View File

@ -53,3 +53,12 @@ composed together in a chain."
:from-end t
:initial-value (apply fn1 args))))
#'identity))
(defmacro with-gensyms (syms &body body)
"Binds a whole list of variables to gensyms."
`(let ,(mapcar #'(lambda (s)
`(,s (gensym)))
syms)
,@body))

View File

@ -8,6 +8,7 @@
#:group
#:flatten
#:compose
#:with-gensyms
;; lol.lisp : utilities from Let Over Lambda
#:defmacro!
@ -55,4 +56,5 @@
#:with-string-output-to-file
#:with-read-from-file
#:with-write-to-file
#:in
))