Lisp 链接函数宏

标签 lisp macros common-lisp chaining piping

是否有现成的 lisp 宏允许链接(管道)函数?我找不到一个。我将尝试用这个例子来解释我的意思。

而不是像这样将 let* 与许多未使用的中间变量一起使用:

(let*
  ((var1 (f1 x y))
   (var2 (f2 x var1))
   (var3 (f1 var2 z)))
 var3)

我想这样写:

(->
  (f1 x y)
  (f2 x _)
  (f1 _ z))

其中,显然 _ 将是前一个表达式的返回值。如果可以使用 _1_2 ... 来引用以前返回的值,那么加号就是。

这就是想法,确切的语法并不那么重要。

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

最佳答案

是这样的吗?

(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 作为引用,但更改它以便它也为每个后续级别绑定(bind) _ 并不难。

关于Lisp 链接函数宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2162601/

相关文章:

lisp - 为什么 null 谓词称为 null,而不是 nullp?

macros - 将列表传递给 Common Lisp 中的宏

scheme - 为什么使用 list 或 cons 构建时相同的数据打印不同?

c++ - 在宏的帮助下创建类属性

javascript - Sweet.js - 可以在多个文件中使用宏吗?

C++ 宏 "if class is defined"

functional-programming - 方案编码风格问题

lambda - 这段 Lisp 代码是什么意思?

lisp - 避免 Clozure lisp 中的回声(菜鸟)

list - common lisp 自定义比较函数