Is there a ready made lisp macro that allows chaining (piping) of functions? I couldn't find one. I'll try to explain what I mean with this example.
Instead of using let* with lots of unused intermediate variables like this:
(let*
((var1 (f1 x y))
(var2 (f2 x var1))
(var3 (f1 var2 z)))
var3)
I would like to have it written like this:
(->
(f1 x y)
(f2 x _)
(f1 _ z))
where, obviously _ will be return value from previous expression. A plus is if would be possible to use _1, _2, ... to reference previously returned values.
This is the idea, exact syntax is not that important.
I know this is not that hard to write, but seems so useful that it has to be written already.
Something like this?
(defun chain-expander (forms)
(cond ((null (cdr forms)) (car forms))
(t `(let ((it ,(car forms)))
,(chain-expander (cdr forms))))))
(defun chain-counted-expander (forms counter)
(cond ((null (cdr forms)) (car forms))
(t (let* ((name (format nil "_~d" counter))
(anaphora (or (find-symbol name) (intern name))))
`(let ((,anaphora ,(car forms)))
,(chain-counted-expander (cdr forms) (1+ counter)))))))
(defmacro chain (&body forms)
(chain-expander forms))
If you'd prefer something where _1, _2, and so on is usable, simply replace the call to CHAIN-EXPANDER with a call to CHAIN-COUNTED-EXPANDER (with your preferred first number, I'd suggest either 0 or 1). Note that it explicitly only caters to using _N as a reference, but changing it so that it also binds _ for each subsequent level is not very hard.
Why not just
(f1 (f2 x (f1 x y)) z)
?
Or make that into a function ?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With