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