有没有办法使用宏来做类似词法闭包的事情?我想要做的是使以下宏成为本地递归助手,它在每个组合上调用一个函数,而不是像现在在 repl 结果中调用宏那样生成一个列表:
CL-USER> (combinations nil '(1 2 3) '(4 5 6))
((1 4) (1 5) (1 6) (2 4) (2 5) (2 6) (3 4) (3 5) (3 6))
我想要的是一个宏,它接受一个函数和任意数量的列表,并导致嵌套循环在每个组合上调用该函数。我对 lisp 很陌生,这是我编写的第一个宏,超越了 'nif' 克隆等,因此任何建议都值得赞赏。
我试图将宏转换为宏中的宏,该宏需要一个函数,并且行 '(nreverse (list ,item ,@vars))' 被替换为 '(func (nreverse (list ,item ,@vars) ))' 但我收到错误消息说 func 是一个未定义的变量或函数。
这是原始功能:
(defmacro combinations (vars &rest lsts)
(with-gensyms (item)
`(loop for ,item in ,(car lsts) ,(if (null (cdr lsts)) 'collecting 'nconcing)
,(if (null (cdr lsts))
`(nreverse (list ,item ,@vars))
`(combinations (,item ,@vars) ,@(cdr lsts))))))
这就是我用宏程序尝试过的并得到未定义的函数'func'错误。
(defmacro for-all-combonations (func &rest lst)
(macrolet ((for-all (vars &rest lsts)
(with-gensyms (item)
`(loop for ,item in ,(car lsts) ,(if (null (cdr lsts))
'collecting 'nconcing)
,(if (null (cdr lsts))
`(func (nreverse (list ,item ,@vars)))
`(for-all (,item ,@vars) ,@(cdr lsts)))))))
(for-all nil lst)))