它是否与ELisp中的Scheme define-syntax
有任何类比?
在define-syntax
我可以指定一些关键字,而在elisp defmacro
似乎我不能。
编辑:似乎我不是很了解你,或者我的问题不明确。
在方案中,可以使用保留字来定义宏,如
(循环
for
一个in
某些列表(循环
while
...
在Emacs Lisp中,我发现无法引入这种糖。 至多,我可以制作宏,必须像
一样调用(循环 - 列表 (做很多事......)
可读性至关重要
答案 0 :(得分:6)
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的宏系统虽然不同。
在foo
的帮助下,可以在R5RS方案中指定与syntax-rules
关联的宏扩展器。这允许您使用模式匹配来指定重写规则(语法规则表单将在内部评估为函数)。
其他差异:R5RS Scheme中的宏扩展算法会帮助您无意中引入与程序其他部分名称冲突的名称(例如来自库,您没有写自己的名字)。历史
由于命名空间在Lisp中的工作方式,这个问题在Lisp中并不是一个大问题,但它可能会出错。
历史上,Scheme和Elisp都使用相同的宏扩展算法,但随后Schemers开始尝试其他算法。 R4RS中引入了“语法规则”系统,但进化并未止步于此。现在所有现代Scheme实现都有(变体)“syntax-case”系统。
一些实现已经完成了使扩展算法与模块(Racket,R6RS实现等)一起工作的工作。
简而言之,当您阅读有关Scheme宏系统的信息时,请注意仔细检查您正在阅读的变体。如果您正在阅读有关限制的内容,那么很可能您已经在(现在很旧的)syntax-rules
系统上找到了一个文本。