我对在scheme中定义宏感到困惑

我对在scheme中定义宏感到困惑,scheme,lisp,Scheme,Lisp,下面两个定义宏之间有什么区别 (define-macro (f x) (+ x 2)) (define-macro (g x) (list '+ x 2)) 当我计算(f(+23))时,有一个错误,但是第二个很好。为什么?宏将代码转换为新代码。它尽可能早地这样做。如果在函数中使用宏,通常在创建该函数时,在代码执行之前很久,宏就会被展开 (f(+23))将应用宏函数f,其值'(+23)为x。它将尝试(+'(+23)2),其结果是新代码完全替换整个(f(+23))。但是,+无法将列表添加到数字中,

下面两个定义宏之间有什么区别

(define-macro (f x) (+ x 2))
(define-macro (g x) (list '+ x 2))

当我计算(f(+23))时,有一个错误,但是第二个很好。为什么?

宏将代码转换为新代码。它尽可能早地这样做。如果在函数中使用宏,通常在创建该函数时,在代码执行之前很久,宏就会被展开

(f(+23))
将应用宏函数
f
,其值
'(+23)
x
。它将尝试
(+'(+23)2)
,其结果是新代码完全替换整个
(f(+23))
。但是,
+
无法将列表添加到数字中,因此创建这样的宏毫无意义

(g(+23))
将应用宏函数
g
,其值为
'(+23)
x
。 它将尝试
(列出“+”(+23)2))
,其结果是
(+(+23)2)
。然后将其逐字放在
(g(+23))
的代码位置,就好像在程序开始执行之前一直是
(+(+23)2)
。它之所以有效,是因为
(+(+23)2)
是一个有效的表达式

理解宏不计算值是很重要的。它以一种格式获取代码,并以另一种格式创建新代码。我们可以制作
let1

(let1 x (+ 10 2)
  (+ x x))
它应该被翻译成

(let ((x (+ 10 2)))
  (+ x x))
因此,宏是:

(define-macro (let1 name expression . body)
  `(let ((,name ,expression)) ,@body))

注意:
定义宏
未在任何版本的方案中指定。许多sheme实现都使用略微不同的语法和规范实现了
defmacro
define macro
。因此,使用define宏的代码不是Scheme代码,而是由实现者指定的方言。我的代码在
#lang racket
中使用
(要求兼容性/defmacro)
进行了测试,但它可能无法在您的方案实现中工作。Scheme中唯一的可移植宏系统是
使用
语法规则定义语法

如何编译?什么错误?请包含完整的错误消息。
定义宏
据我所知不是方案的一部分:您应该指定您正在使用的实现。