Clojure中缺少卫生宏会导致哪些实际问题?


11

我听说Clojure宏易于编写,但不如Racket的卫生宏可靠。我的问题分为两部分:

  1. 如何gensym从卫生宏有什么不同?
  2. 球拍宏提供了Clojure不提供的哪些功能?(无论是安全性,可组合性还是其他)

2
卫生宏是保证扩展不会引起标识符意外捕获的宏。在引入卫生宏之前,意外捕获的一般问题在Lisp社区中众所周知。宏编写者将使用会生成唯一标识符(例如gensym)的语言功能,或者使用混淆的标识符来避免该问题。卫生宏是集成到宏扩展器本身中的捕获问题的程序化解决方案。 zh.wikipedia.org/wiki/Hygienic_macro
罗伯特·哈维

3
因为[Racket]卫生宏系统对宏的工作原理有深入的了解,所以您的宏已很好地集成到环境中:语法高亮显示正确,自动变量重命名正确,交叉引用正确,其他所有流畅的[Racket] IDE功能。换句话说,卫生不仅可以保护您免受诸如变量捕获之类的简单错误的侵害,还可以使您的代码通过普通LISP根本不存在的工具进行正式分析。 randomhacks.net/2002/09/13/hygienic-macros
罗伯特·哈维

Answers:


6

卫生宏的优点不是语言功能之一-您可以编写具有良好卫生习惯的宏,gensym并在正确的时间使用仔细的引用/取消引用。但是,卫生宏确保您的宏具有良好的卫生习惯。在这方面,它有点像类型检查。

卫生宏可能还具有工具优势。大多数卫生宏系统都会对宏的功能及其执行方式进行严格控制(例如,syntax-case扩展Scheme定义的宏时,您将无法执行任意代码)。这样可以使编写“理解”宏的程序变得更容易,并且可以提供其他工具支持。

另一方面,在某些情况下,不卫生的宏可能会有用。例如,如果您实际上捕获特定变量的绑定(例如,回指),那么我认为如果您只有卫生宏,那您就不走运了。


2
gensym防止宏意外与宏用户发生混乱,但不能防止宏用户与宏发生混乱。例如,宏用户可以重新定义if或类似的内容。(“为什么有人会这样做”这个问题是无关紧要的。这是一个简单的示例,说明了这是可能的,并且对非卫生宏进行推理很棘手)
Phil

2
不卫生的宏肯定有用。我不确定Scheme,但是Racket有很多“卫生弯曲”操作。语言的宏默认情况下是卫生的。当您破坏卫生时,它们只会使您非常清醒。
菲尔(Phil)2016年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.