macroexpand-1 和 Macrolet 之间的意外交互

问题描述 投票:0回答:1

考虑 Common Lisp 中的以下形式序列(在 Windows 的 SBCL 2.4.2 中执行评估):

(defmacro double-g (x)
  (list (quote +) x x))

(macroexpand-1 (quote (double-g 3))) => (+ 3 3), T

(macrolet ((double-l (x) (list (quote +) x x)))
  (macroexpand-1 (quote (double-l 3))))
=> (DOUBLE-L 3), NIL

有人可以帮助我理解为什么第二和第三种形式评估出不同的结果吗?

我预计第二和第三种形式会得到相同的结果。

macros common-lisp
1个回答
0
投票

问题:您将尝试在错误的环境中扩展宏。

macrolet
定义了本地宏,但
macroexpand-1
看不到它。

CL-USER 23 > (defmacro expand-1-form (form &environment env)
               (list 'quote (macroexpand-1 form env)))
EXPAND-1-FORM

上面定义了一个宏,它传递当前环境,然后可以通过变量

env
使用。该宏使用
macroexpand-1
扩展了这种形式,并将环境传递给它。扩展以引用形式返回。

现在我们可以使用宏

double-l
来扩展本地宏
expand-1-form
:

CL-USER 24 > (macrolet ((double-l (x) (list (quote +) x x)))
               (expand-1-form (double-l 3)))
(+ 3 3)

上面扩展了宏expand-1-form,传递当前环境。然后用该环境调用

macroexpand-1

© www.soinside.com 2019 - 2024. All rights reserved.