来自CLHS
symbol-macrolet通过词法为每个符号宏建立扩展函数。
...
可以通过let来使用symbol-macrolet。
这允许以下代码工作(* b * x内部绑定为'1'):
CT> (with-slots (x y z) *b*
(let ((x 10))
(format nil "~a ~a ~a" x y z)))
"10 2 3"
我的问题是:symbol-macro如何知道哪些表单可以隐藏它?我问,因为宏不能保证let还没有重新定义,或者用户没有创建另一个表单来执行与let相同的工作。这是一个特殊的'哑'案例,只是寻找cl:let符号?还是有更先进的技术在进行?
我很乐意编辑这个问题,如果这个问题太模糊,我很难明确表达这个问题。
答案 0 :(得分:5)
见3.1.1.4及周围材料。
引用来自哪里?我不认为这是完全正确的,因为在词汇环境中,let不是唯一可以影响macrolet建立的名称的东西。
我认为,揭示词汇环境不仅仅是一个抽象的概念,还有一个实际的数据结构能够体现它,这并不会造成太大的伤害。词典环境在编译时通过&环境绑定机制可用于宏。宏可以使用它来获取进入环境的窗口,并且有一个使用环境的协议。因此,举一个简单的例子,可以创建对词法环境中的声明敏感的宏,例如,如果变量被声明为fixnum,则扩展一种方式。
环境的实现由实施者决定,但是它只是一堆名称和名称的信息。所以lambda绑定,macrolet,标签,let *等等只是将新名称推入该堆栈,从而遮蔽旧名称。词法声明正在添加有关名称的信息。
然后,编译器或赋值器使用环境(堆栈)来指导生成的代码或执行的行为方式。值得注意的是,这种数据结构不需要存活到运行时,尽管通常它的一些后代可以帮助调试器。
所以回答你的问题:macrolet并不知道它和& body可能正在做什么形式。
答案 1 :(得分:3)
正如您所见,SYMBOL-MACROLET是Common Lisp的内置功能。就像LET一样。无法重新定义这些特殊运算符,并且不允许这样做。
Common Lisp只有一组固定的特殊运算符,无法由用户定义。只定义了这些:Common Lisp special operators。
由于宏将被扩展,它们将扩展为基本原语:函数调用和特殊形式。因此,编译器/解释器实现了symbol-macrolet,并且该任务受到原始形式数量的限制。如果用户实现了他/她自己的LET,那么最终这个实现也可以归结为函数调用和特殊形式 - 最终将宏的所有用途扩展到那些。但这些都是已知的,而symbol-macrolet并没有什么新东西。