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