The Kitchen Sink and Other Oddities

Atabey Kaygun

Threading Macros in Common Lisp

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:

Implementation

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:

In 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)