如何重写这个 Common Lisp 宏来避免反引号?
How to re-write this Common Lisp macro avoiding the back-quote notation?
我正在尝试通过 Common Lisp:对符号计算的简单介绍 来学习 Common Lisp。此外,我正在使用 SBCL、Emacs 和 Slime。
在上一章的宏中,作者给出了重写内置incf
宏的例子。他用两种不同的方法教授这个概念:使用反引号和不使用反引号。如:
(defmacro list-notation-my-incf (x)
(list 'setq x (list '+ x 1)))
(defmacro backquote-notation-my-incf (x)
`(setq ,x (+ ,x 1)))
后面作者再介绍一个例子:
In the example below, TWO-FROM-ONE is a macro that takes a function
name and another object as arguments; it expands into a call to the
function with two arguments, both of which are the quoted object.
他只用反引号来做:
(defmacro two-from-one (func object)
`(,func ',object ',object))
它按预期工作:
CL-USER> (two-from-one cons stack-overflow)
(STACK-OVERFLOW . STACK-OVERFLOW)
使用 slime-macroexpad-1
,我有:
(CONS 'STACK-OVERFLOW 'STACK-OVERFLOW)
作为我为自己创建的练习,我尝试做同样的事情,但避免了反引号。不幸的是,我无法让它工作:
(defmacro list-two-from-one (func object)
(list func (quote object) (quote object)))
Slime 抛出错误:
The variable OBJECT is unbound.
[Condition of type UNBOUND-VARIABLE]
做一个宏展开,我看到:
(CONS OBJECT OBJECT)
如果我尝试不同的方法,它似乎更接近,但它也不起作用:
(defmacro list-two-from-one (func object)
(list func object object))
抛出错误:
The variable STACK-OVERFLOW is unbound.
[Condition of type UNBOUND-VARIABLE]
最后,宏扩展表示:
(CONS STACK-OVERFLOW STACK-OVERFLOW)
我觉得卡住了。如何在不使用反引号的情况下成功重写宏?
谢谢。
您的宏应扩展为:
CL-USER 10 > (macroexpand '(two-from-one2 cons stack-overflow))
(CONS (QUOTE STACK-OVERFLOW) (QUOTE STACK-OVERFLOW))
所以用 quote
创建列表,如下所示:
(defmacro two-from-one2 (func object)
(list func (list 'quote object) (list 'quote object)))
测试:
CL-USER 9 > (two-from-one2 cons stack-overflow)
(STACK-OVERFLOW . STACK-OVERFLOW)
你要找的是
(defmacro list-two-from-one (func object)
(list func (list 'quote object) (list 'quote object)))
基本上,宏的主体应该 return 代码,在评估时 会产生所需的结果。
即宏体应该产生 (CONS 'STACK-OVERFLOW 'STACK-OVERFLOW)
.
由于 'a
与 (quote a)
相同,您希望宏生成
(CONS (QUOTE STACK-OVERFLOW) (QUOTE STACK-OVERFLOW))
这就是我上面的 defmacro
returns.
我正在尝试通过 Common Lisp:对符号计算的简单介绍 来学习 Common Lisp。此外,我正在使用 SBCL、Emacs 和 Slime。
在上一章的宏中,作者给出了重写内置incf
宏的例子。他用两种不同的方法教授这个概念:使用反引号和不使用反引号。如:
(defmacro list-notation-my-incf (x)
(list 'setq x (list '+ x 1)))
(defmacro backquote-notation-my-incf (x)
`(setq ,x (+ ,x 1)))
后面作者再介绍一个例子:
In the example below, TWO-FROM-ONE is a macro that takes a function name and another object as arguments; it expands into a call to the function with two arguments, both of which are the quoted object.
他只用反引号来做:
(defmacro two-from-one (func object)
`(,func ',object ',object))
它按预期工作:
CL-USER> (two-from-one cons stack-overflow)
(STACK-OVERFLOW . STACK-OVERFLOW)
使用 slime-macroexpad-1
,我有:
(CONS 'STACK-OVERFLOW 'STACK-OVERFLOW)
作为我为自己创建的练习,我尝试做同样的事情,但避免了反引号。不幸的是,我无法让它工作:
(defmacro list-two-from-one (func object)
(list func (quote object) (quote object)))
Slime 抛出错误:
The variable OBJECT is unbound.
[Condition of type UNBOUND-VARIABLE]
做一个宏展开,我看到:
(CONS OBJECT OBJECT)
如果我尝试不同的方法,它似乎更接近,但它也不起作用:
(defmacro list-two-from-one (func object)
(list func object object))
抛出错误:
The variable STACK-OVERFLOW is unbound.
[Condition of type UNBOUND-VARIABLE]
最后,宏扩展表示:
(CONS STACK-OVERFLOW STACK-OVERFLOW)
我觉得卡住了。如何在不使用反引号的情况下成功重写宏?
谢谢。
您的宏应扩展为:
CL-USER 10 > (macroexpand '(two-from-one2 cons stack-overflow))
(CONS (QUOTE STACK-OVERFLOW) (QUOTE STACK-OVERFLOW))
所以用 quote
创建列表,如下所示:
(defmacro two-from-one2 (func object)
(list func (list 'quote object) (list 'quote object)))
测试:
CL-USER 9 > (two-from-one2 cons stack-overflow)
(STACK-OVERFLOW . STACK-OVERFLOW)
你要找的是
(defmacro list-two-from-one (func object)
(list func (list 'quote object) (list 'quote object)))
基本上,宏的主体应该 return 代码,在评估时 会产生所需的结果。
即宏体应该产生 (CONS 'STACK-OVERFLOW 'STACK-OVERFLOW)
.
由于 'a
与 (quote a)
相同,您希望宏生成
(CONS (QUOTE STACK-OVERFLOW) (QUOTE STACK-OVERFLOW))
这就是我上面的 defmacro
returns.