Last active
May 18, 2017 16:39
-
-
Save serialhex/61c20a27e4ce877771c8926a6a477b3f to your computer and use it in GitHub Desktop.
A Common Lisp macro that threads a value through a handful of forms, updating that value if the predicate returns true.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; from On Lisp | |
(defun single (lst) | |
(and (consp lst) (not (cdr lst)))) | |
(defmacro cond-<> (data &body body) | |
"A combination of this: https://clojuredocs.org/clojure.core/cond-%3E | |
and this: https://github.com/rplevy/swiss-arrows#a-generalization-of-the-arrow | |
returns last value of <>" | |
(let ((<> (intern "<>"))) | |
`(let ((<> ,data)) | |
,@(mapcar | |
(lambda (l) | |
`(if ,(car l) | |
(setf <> | |
,(if (single (cdr l)) | |
(cadr l) | |
`(progn ,@(cdr l)))))) | |
body) | |
<>))) | |
;; Example | |
(cond-<> (list 1 2 3) | |
((member 4 <>) (mapcar (lambda (x) (* x x)) <>)) | |
((is-full-moon-p) (do-crazy-database-transaction <> :its-a-full-moon) (reduce #'* <>)) | |
((cust-want-min-max-p) (list (apply #'min <>) (apply #'max <>)))) | |
;; Expands to: | |
(progn | |
(setf <> (list 1 2 3)) | |
(if (member 4 <>) | |
(setf <> (mapcar (lambda (x) (* x x)) <>))) | |
(if (is-full-moon-p) | |
(setf <> | |
(progn (do-crazy-database-transaction <> :its-a-full-moon) | |
(reduce #'* <>)))) | |
(if (cust-want-min-max-p) | |
(setf <> (list (apply #'min <>) (apply #'max <>)))) | |
<>) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment