macros - 符号宏如何处理让阴影?

标签 macros common-lisp

来自 CLHS

symbol-macrolet lexically establishes expansion functions for each of the symbol macros named by symbols.

...

The use of symbol-macrolet can be shadowed by let.


这允许以下代码工作(内部 *b* x 绑定(bind)到 '1'):
CT> (with-slots (x y z) *b* 
      (let ((x 10))
        (format nil "~a ~a ~a" x y z)))
"10 2 3"
我的问题是:符号宏如何让知道哪些形式可以影响它?我问,因为宏不能保证 let 没有被重新定义,或者用户没有创建另一个表单来完成与 let 相同的工作。这是只寻找 cl:let 符号的特殊“愚蠢”案例吗?还是有一些更先进的技术在进行?
如果它太模糊,我很乐意编辑这个问题,我很难表达这个问题。

最佳答案

见 3.1.1.4 及周边 Material 。

那句话出自哪里?我不认为它是完全正确的,因为 let 不是唯一可以在词法环境中掩盖由 macrolet 建立的名称的东西。

我不认为揭示词汇环境不仅仅是一个抽象概念,而是有一个实际的数据结构来表现它,这并没有多大害处。词法环境在编译时通过 &environment 绑定(bind)机制可供宏使用。宏可以使用它来获得进入环境的窗口,并且有一个使用环境的协议(protocol)。因此,举一个简单的例子,可以编写对词法环境中的声明敏感的宏,例如,如果变量声明为 fixnum,则扩展一种方式。

环境的实现由实现者决定,但它只是一堆带有名称信息的名称。因此 lambda 绑定(bind)、macrolet、标签、let* 等只是将新名称推送到该堆栈中,从而掩盖旧名称。词法声明正在增加关于名称的信息。

然后编译器或评估器使用环境(堆栈)来指导生成的代码或执行的行为方式。值得注意的是,这种数据结构不需要在运行时继续存在,尽管它的某些后代通常会帮助调试器。

所以回答你的问题:macrolet 不知道它的 &body 可能在做什么形式。

关于macros - 符号宏如何处理让阴影?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21217562/

相关文章:

c++ - 如何在运行时生成函数?

common-lisp - 为什么这个来自 ANSI Common Lisp 的作用域示例不能按预期工作?

lisp - Common Lisp 中的动态变量和词法变量

c - 如何在 if 语句中的条件下创建宏

dependencies - 如何管理常见的 lisp 依赖项?

emacs - 在 ALLEGRO-CL 免费版中安装 Quicklisp 库

common-lisp - Common Lisp 的 "loop for"宏如何与多个 "and"ed 计数器一起工作?

haskell - 什么可以用 Haskell monad 完成而不能用 Lisp 宏完成,反之亦然?

macros - 如何在 lisp 中用 if 形式定义递归 cond 宏?

c - 这个 C 宏主体中的三重点是如何工作的?