Lisp链接函数宏
是否有现成的lisp宏允许函数链接(管道)?我找不到。我将试着用这个例子来解释我的意思 不要将let*与大量未使用的中间变量一起使用,例如: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))
(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*的级联,其可读性通常更高。