Lisp链接函数宏

Mar*_*rko 4 lisp macros common-lisp piping chaining

是否有现成的lisp宏,允许链接(管道)功能?我找不到一个.我会尝试用这个例子来解释我的意思.

而不是使用let*和许多未使用的中间变量,如下所示:

(let*
  ((var1 (f1 x y))
   (var2 (f2 x var1))
   (var3 (f1 var2 z)))
 var3)
Run Code Online (Sandbox Code Playgroud)

我想这样写:

(->
  (f1 x y)
  (f2 x _)
  (f1 _ z))
Run Code Online (Sandbox Code Playgroud)

其中,显然_将是前一个表达式的返回值.加号是否可以使用_1,_2,...来引用先前返回的值.

这是一个想法,确切的语法并不重要.

我知道这并不难写,但看起来非常有用,必须已经写好了.

Vat*_*ine 7

像这样的东西?

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

如果你喜欢_1,_2等可以使用的东西,只需调用CHAIN-EXPANDER来调用CHAIN-COUNTED-EXPANDER(用你喜欢的第一个数字,我建议0或1) .请注意,它明确地仅提供使用_ N作为参考,但更改它以便它也为每个后续级别绑定_并不是很难.


Chr*_*röm 5

为什么不只是

(f1 (f2 x (f1 x y)) z)
Run Code Online (Sandbox Code Playgroud)

?

或者把它变成一个函数?