Skip to content

Instantly share code, notes, and snippets.

@serialhex
Last active May 18, 2017
Embed
What would you like to do?
A Common Lisp macro that threads a value through a handful of forms, updating that value if the predicate returns true.
;; 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