Lisp macrolet上的词汇闭包?

Lisp macrolet上的词汇闭包?,lisp,common-lisp,lexical-closures,Lisp,Common Lisp,Lexical Closures,有没有一种方法可以使用macrolet实现类似词法闭包的功能?我要做的是使以下宏成为一个本地递归帮助器,在每个组合上调用函数,而不是像现在在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还

有没有一种方法可以使用macrolet实现类似词法闭包的功能?我要做的是使以下宏成为一个本地递归帮助器,在每个组合上调用函数,而不是像现在在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”克隆之类的基础上编写的第一个宏,因此任何建议都非常感谢

我曾尝试将宏转换为接受函数的宏中的macrolet,并将行“(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))))))
这是我用macrolet尝试过的,得到了未定义的函数“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)))

宏不是CommonLisp中的第一类对象,因此不能将词法闭包等效为宏。通过创建一个函数,生成一个有效Lisp程序列表,然后对其求值,可以获得类似的效果


不过,这可能不是解决你问题的好办法。正如Rainer Joswig所说,宏用于操作源代码。当你想要一种语言中没有内置的新语法形式时,可以使用它们。不要在可以用普通函数编写所需内容的地方使用宏。

您能解释一下为什么要使用宏吗?(让((a’((1 2 3)(4 5 6)))(组合nil a))应该做什么?它应该返回“((1 2 3))((4 5 6))),它是所有组合的列表,从每个组合的每个输入列表中获取一个元素。我用宏来做这件事,因为这就是我现在一直在探索的。我可以不用宏,但我想尝试写一个比nif更复杂的宏。这给了我一个机会去发现什么是可以做的,什么是不可以做的,我永远不会怀疑macrolet是否可以以这种方式使用。希望完成这篇文章后,我能更好地理解宏。我认为这对于宏来说没有意义。宏用于计算源代码,而不是数据。如果你想计算数据,数据需要在宏展开时存在——通常不是这样。好吧,你说服了我。“我想这是本次探索的终点了。”安德鲁·迈尔斯——关于一级宏的概念已经有了一些探索。我最近读到的是Paul Graham考虑Arc的想法。我认为他最终搁置了它,因为它使编译器变得更加复杂,因为不确定的好处。