【发布时间】:2011-09-29 07:33:08
【问题描述】:
我的理解是Clojure's homoiconicity的存在是为了让编写宏更容易。
基于this stackoverflow thread,似乎很少使用宏,除了不使用高阶函数的DSL。
有人可以分享一些在现实生活中如何使用宏的例子吗?
【问题讨论】:
标签: clojure
我的理解是Clojure's homoiconicity的存在是为了让编写宏更容易。
基于this stackoverflow thread,似乎很少使用宏,除了不使用高阶函数的DSL。
有人可以分享一些在现实生活中如何使用宏的例子吗?
【问题讨论】:
标签: clojure
homoiconicity 使编写 Clojure 宏变得非常容易,这是正确的。基本上,它们使您能够编写代码来构建您想要的任何代码,利用 Lisp 的“代码就是数据”理念。
同音语言中的宏也非常强大。我在implement a LINQ-like query syntax in just three lines of Clojure 找到了一个有趣的示例演示文稿。
一般来说,Clojure 宏可能有用的原因有很多:
控制结构 - 可以使用永远不能用函数表示的宏来创建某些控制结构。例如,您不能将if 写为函数,因为如果它是一个函数,那么它必须评估所有三个参数,而使用宏您可以让它只评估两个(条件值和真或虚假表达)
编译时优化 - 有时您希望基于一个已知的或可以在编译时计算的常数来优化您的代码。例如,您可以创建一个“日志记录”函数,该函数仅在代码以调试模式编译时记录,但在生产应用程序中创建零开销。
代码生成/样板消除 - 如果您需要生成大量具有相似结构的非常相似的代码,那么您可以使用宏从几个参数中自动生成这些代码。如果您讨厌样板,那么宏就是您的朋友。
创建新语法 - 如果您发现需要一种有用的特定语法(可能封装一个通用模式),那么您可以创建一个宏来实现它。例如,一些 DSL 可以通过额外的语法来简化。
创建具有全新语义的新语言(感谢 SK-Logic!)理论上,您甚至可以使用宏创建新语言,这将有效地编译您的新语言将语言转换为 Clojure。新语言甚至不必像 Lisp:例如,它可以解析和编译任意字符串。
一条重要的建议是仅在需要宏且函数不起作用时才使用它们。大多数问题都可以用函数来解决。除了宏对于简单的情况来说太过分了,函数还有一些内在的优势:它们更灵活,可以存储在数据结构中,可以作为参数传递给更高阶的函数,更容易让人理解等等。
【讨论】:
creating new semantics。即,在宿主语言之上为任意复杂语言构建编译器。在大多数情况下,宏是此任务的唯一选择,因为其他任何东西都太低效了。