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