Lisp链接函数宏

Lisp链接函数宏,lisp,macros,common-lisp,chaining,piping,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)) 我想把它写成这样: (let* ((var1 (f1 x y)) (var2 (f2 x var1))

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

不要将let*与大量未使用的中间变量一起使用,例如:

(let*
  ((var1 (f1 x y))
   (var2 (f2 x var1))
   (var3 (f1 var2 z)))
 var3)
(->
  (f1 x y)
  (f2 x _)
  (f1 _ z))
我想把它写成这样:

(let*
  ((var1 (f1 x y))
   (var2 (f2 x var1))
   (var3 (f1 var2 z)))
 var3)
(->
  (f1 x y)
  (f2 x _)
  (f1 _ z))
其中,显然是前面表达式的返回值。如果可以使用\U 1\U 2、。。。引用以前返回的值

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

我知道这并不难写,但似乎很有用,必须已经写了。

为什么不直接写呢

(f1 (f2 x (f1 x y)) z)
?

或者把它变成一个函数?

通过类似的方式

(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)) (除油扩链器(表格) (条件((空白(cdr表格))(car表格)) (t`(let((it,(car forms))) ,(扩链器(cdr表格(()()))) (除链计数扩展器(表格计数器) (条件((空白(cdr表格))(car表格)) (t(let*((名称(格式为“无”计数器)) (回指(或(查找符号名)(实习生姓名))) `(let(,回指,(car形式))) ,(链式计数扩展器(cdr形式)(1+计数器‘‘‘‘‘‘‘‘‘‘‘) (定义宏链和实体形状) (扩链器形式)
如果您喜欢使用_1、_2等等,只需将对CHAIN-EXPANDER的调用替换为对CHAIN-COUNTED-EXPANDER的调用(使用您首选的第一个数字,我建议使用0或1)。请注意,它明确地只适合使用_N作为引用,但更改它以便它也为每个后续级别绑定_并不困难。

您可以从

宏将上一个表达式的值绑定到“it”,但如果需要,可以将其更改为“\u1”。
当然,您也可以将名称更改为->或您喜欢的任何其他名称。

您可能会发现这个问题很有趣:


我对这个问题的回答与梵蒂冈对这个问题的回答相似,但没有计算在内;顺便说一句,我认为计数是非常脆弱的——当您更新代码时,您可能会引入重新排序错误。也许最好提供一种方法来命名以前的结果——但实际上,除了最后一个结果之外,我很少需要其他结果。如果您需要它们,也许您应该编写一个函数,而不是一个链接表达式。

嗯,第二种方法看起来更可读,尤其是对于较长的函数序列。实际上,我觉得这更容易理解。通过管道版本,我试图重建我脑海中的价值流。这里的版本更清楚。管道版本需要“命令式”思维。谢谢。这正是我想要的。纯粹出于好奇,您是否经常使用此代码?对于(f1(f2 x(f1 x y))z)而不是let*的级联,其可读性通常更高。