diff --git a/docs/flip.lisp b/docs/flip.lisp new file mode 100644 index 0000000..0c5739a --- /dev/null +++ b/docs/flip.lisp @@ -0,0 +1,5 @@ +CL-USER> (format t "(- 7 3) -> ~A~%" + (funcall (flip #'- 3) 7)) +(- 7 3) -> 4 +NIL + diff --git a/docs/manual.scr b/docs/manual.scr index d39232b..3babdc4 100644 --- a/docs/manual.scr +++ b/docs/manual.scr @@ -117,6 +117,8 @@ some functions I found useful.) @code(@include[path=examples.lisp start=1 end=5]()) @cl:doc(function effector) @cl:doc(function empty-or-nil-p) +@cl:doc(function flip) +@code(@include[path="flip.lisp"]()) @cl:doc(function macroexpand-n) @cl:doc(function mksymb) @cl:doc(function mkkw) @@ -224,6 +226,8 @@ For example, from @c(kmop/kmop.lisp): @cl:doc(macro condlet*) @cl:doc(macro iflet) @cl:doc(macro iflet*) +@cl:doc(macro orlet) +@code(@include[path="orlet.lisp"]()) @cl:doc(macro unlesslet) @cl:doc(macro unlesslet*) @cl:doc(macro whenlet) @@ -360,6 +364,9 @@ described in "Miscellaneous utilities" under "Vector-related".) @item(@c(flatten) is a function defined in @c(on.lisp), described in "On Lisp utilities".) +@item(@c(flip) is a function defined in @c(kutils.lisp), described in +"Miscellaneous utilities" under "General".) + @item(@c(group) is a function defined in @c(kutils.lisp), described in "On Lisp utilities".) @@ -410,6 +417,9 @@ utilities".) @item(@c(new-vector) is a function defined in @c(kutils.lisp), described in "Miscellaneous utilities" under "Vector-related".) +@item(@c(orlet) is a macro defined in @c(macros.lisp), described in +"Macros" under "Let macros".) + @item(@c(partial) is a function defined in @c(kutils.lisp), described in "Miscellaneous utilities" under "Clojure-inspired functions".) @@ -485,6 +495,7 @@ Alphabetical documentation for all exported symbols. @cl:doc(function enable-hash-table-reader) @cl:doc(function extend-vector) @cl:doc(function flatten) +@cl:doc(function flip) @cl:doc(function group) @cl:doc(function hash-table-to-alist) @cl:doc(function hashkeys) @@ -499,6 +510,7 @@ Alphabetical documentation for all exported symbols. @cl:doc(function mksymb) @cl:doc(function new-hash-table) @cl:doc(function new-vector) +@cl:doc(macro orlet) @cl:doc(function partial) @cl:doc(function partition) @cl:doc(macro sethash) diff --git a/docs/orlet.lisp b/docs/orlet.lisp new file mode 100644 index 0000000..05fc4f3 --- /dev/null +++ b/docs/orlet.lisp @@ -0,0 +1,12 @@ +(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)))))))) diff --git a/kutils.lisp b/kutils.lisp index cecca4d..c36f77a 100644 --- a/kutils.lisp +++ b/kutils.lisp @@ -46,6 +46,11 @@ additional args provided to the lambda." (lambda (&rest args) (apply fn (append initial-args args)))) +(defun flip (fn y) + "Given a function @c(fn) that takes arguments @c(x) and @c(y), return a lambda with @c(y) applied to the function." + (lambda (x) + (funcall fn x y))) + (defun macroexpand-n (n form) "Expand the macro n times." (let ((new-form form)) diff --git a/macros.lisp b/macros.lisp index 8940d15..a6e4bd9 100644 --- a/macros.lisp +++ b/macros.lisp @@ -4,6 +4,17 @@ ;;; Various utility macros. +(defun orletfun (bindings finally) + (if (null bindings) + finally + `(let (,(first bindings)) + (when ,(first (first bindings)) + ,(orletfun (rest bindings) finally))))) + +(defmacro orlet (bindings &body body) + "For each set of bindings, evaluate them in sequence. If each binding evaluates to T, evaluate @c(body) in a @c(progn)." + (orletfun bindings `(progn ,@body))) + (defmacro whenlet (bindings &body body) "Evaluate the bindings in a let form; if they all evaluate to T, evaluate @c(body) in an implicit @c(progn)." diff --git a/package.lisp b/package.lisp index ae7e8ac..c5bfc09 100644 --- a/package.lisp +++ b/package.lisp @@ -19,6 +19,7 @@ #:drop #:build-list #:partial + #:flip #:macroexpand-n #:mksymb #:mkkw @@ -44,6 +45,7 @@ #:alist-to-hash-table ;; macros.lisp + #:orlet #:whenlet #:whenlet* #:unlesslet