我对在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中唯一的可移植宏系统是使用语法规则定义语法
如何编译?什么错误?请包含完整的错误消息。定义宏
据我所知不是方案的一部分:您应该指定您正在使用的实现。