define-syntax
它与 ELisp中的 Scheme 有什么类比吗?在define-syntax
我可以指定一些关键字,而在 elisp 中defmacro
似乎我不能。编辑:似乎我要么不太了解你,要么我的问题不清楚。在方案中,可以使用保留字定义宏,例如
(循环
for
一些in
列表(循环
while
……</p>
在 Emacs Lisp 中,我发现没有办法引入这种糖。最多,我可以制作宏,必须像这样调用
(循环列表(做很多事情......)
可读性很重要
Scheme 和 Elisp 都有宏系统。“关键字”define-syntax
都defmacro
为用户定义的宏引入了名称。
在实际代码中使用宏 foo 时,假设(foo 1 bar)
宏扩展器必须确定如何将给定的形式 重写为(foo 1 bar)
不包含用户宏的更简单的形式。宏扩展器调用在定义宏foo
时定义的函数。即,它调用您指定的函数,define-syntax
或者defmacro
使用表单的表示,(foo 1 bar)
. 表示可以是“语法对象”或普通列表(这在不同的宏系统中有所不同)。
这是我对 和 之间相似性的define-syntax
看法defmacro
。
R5RS Scheme 和 Elisp 的宏系统是不同的。
与 R5RS 方案中关联的宏扩展器foo
可以在syntax-rules
. 这允许您使用模式匹配来指定重写规则(在内部,语法规则表单将评估为函数)。其他区别:R5RS 方案中的宏扩展算法将帮助您再次无意中引入与程序其他部分的名称冲突的名称(比如来自库,您没有编写自己的名称)。从历史上看,由于名称空间在 Lisp 中的工作方式,这个问题在 Lisp 中并不是什么大问题,但可能会出错。
从历史上看,Scheme 和 Elisp 都使用相同的宏扩展算法,但后来 Schemers 开始尝试其他算法。R5RS 中引入了“语法规则”系统,但演变并没有就此停止。如今,所有现代 Scheme 实现都有(变体)“语法案例”系统。
一些实现已经完成了使此扩展算法与模块(Racket、R6RS 实现等)一起使用的工作。
简而言之,当您阅读 Scheme 宏系统时,请注意准确检查您正在阅读的变体。如果您正在阅读有关限制的内容,那么您很可能在(现在相当旧的)syntax-rules
系统上找到了文本。