I have been doing some clojure
programming for a series of
lectures for some of my students introducing them clojure, lisps and
functional programming in general. One of things I was explaining was
the thread macros ->
and ->>
. I
thought it might be good idea to implement them in Common Lisp. So, here
it goes:
There really isn’t much to talk about the code. So, I am going to
give it here. First, the thread-last macro ->>
which
was easier to implement.
(defmacro ->> (x &rest forms)
(dolist (f forms x)
(setf x
(if (listp f)
(append f (list x))
(list f x)))))
->>
(* I slightly refactored the macros using a suggestion from @simendiferlerin.)
And here is a test:
(->> '(1 3) (append '(4 3 -1)) (mapcar (lambda (x) (* x x))))
(16 9 1 1 9)
This macro takes a form x
and list of partially
evaluated forms f1
, f2
, … , fj
as
an argument. It recursively goes over the list as follows:
f
is the name of a function evaluates
(f x)
f
is a list of expression then appends
x
to f
and evaluates the new formIn either case, the result is fed into the next step as an input.
Now, the thread-first macro ->
which was a little
more complicated.
(defmacro -> (x &rest forms)
(dolist (f forms x)
(setf x
(if (listp f)
(append (list (car f) x) (cdr f))
(list f x)))))
->
It is similar to ->
. But this time if f
is a list, the input is inserted into f
as the second item
right after its car
then evaluated.
And another test:
(-> 2 (cons '(-2 -1 0)) (append '(-10 -20)))
(2 -2 -1 0 -10 -20)