Macros 将Clojure宏用于DSL
我正在从事一个Clojure项目,我经常发现自己在为DSL编写Clojure宏,但我在看一个Clojure视频,其中讲述了一家公司如何在实际工作中使用Clojure,演讲者说,在实际使用中,他们不为DSL使用宏,他们只使用宏来添加一点语法糖分。这是否意味着我应该使用标准函数编写DSL,然后在最后添加几个宏 更新: 在阅读了对这个问题的各种各样(有趣)的回答后,我意识到答案并不像我最初想的那么明确,原因有很多:Macros 将Clojure宏用于DSL,macros,clojure,dsl,higher-order-functions,Macros,Clojure,Dsl,Higher Order Functions,我正在从事一个Clojure项目,我经常发现自己在为DSL编写Clojure宏,但我在看一个Clojure视频,其中讲述了一家公司如何在实际工作中使用Clojure,演讲者说,在实际使用中,他们不为DSL使用宏,他们只使用宏来添加一点语法糖分。这是否意味着我应该使用标准函数编写DSL,然后在最后添加几个宏 更新: 在阅读了对这个问题的各种各样(有趣)的回答后,我意识到答案并不像我最初想的那么明确,原因有很多: 应用程序中有许多不同类型的API(内部、外部) API有多种类型的用户(只想快速完成某
- 分阶段做。定义从DSL到底层Clojure的一长串语言。使每个转换尽可能简单-这样您就能够轻松地维护和调试DSL编译器
- 准备一个DSL组件工具箱,以便在实现DSL时重用。它应该包括不同语义的目标语言(例如,非类型化的渴望函数——它是Clojure本身、非类型化的惰性函数、一阶逻辑、类型化命令、Hindley Millner类型化的渴望函数、数据流等)。对于宏,无缝地组合所有目标语义的属性是很简单的
- 维护一组编译器构建工具。它应该包括解析器生成器(即使您的DSL完全在S表达式中也很有用)、术语重写引擎、模式匹配引擎、图形上一些常见算法的实现(例如,图形着色)等
- 以下是Haskell中使用函数而不是宏的DSL示例:
下面是Simon Peyton Jones讲述此实现的视频:
在开始实现您自己的语言之前,利用Clojure和FP的特性。我认为SK-logic的技巧很好地说明了实现一个完整的语言需要什么。有时值得付出努力,但这种情况很少发生。在某种程度上,我相信这取决于DSL的用途 如果您正在编写一个类似于DSL的库,以便在Clojure代码中使用,并且希望以功能性的方式使用它,那么我更喜欢函数而不是宏。函数对于Clojure用户来说“很好”,因为它们可以动态地组合成更高阶的函数等。例如,您正在编写一个功能性web框架,如 如果您正在编写一个与其他Clojure代码非常独立的命令式DSL,并且您已经决定不需要更高阶的函数,那么使用方法将非常相似,您可以选择最有意义的。例如,您可能正在创建某种业务规则引擎
如果您正在编写一个需要生成高性能代码的专用DSL,那么您可能会希望在大部分时间使用宏,因为它们将在编译时展开以获得最高效率。例如,您正在编写一些图形代码,这些代码需要精确地扩展到OpenGL调用的正确顺序……我是否正确地理解了您提倡的解释而不是编译?不,我认为我们讨论的是不同类型的DSL。我说的是普通的API(用于该库的迷你DSL),而不是嵌入式Prolog。(我认为大多数人并不经常编写完整的语言实现)@nickik,这并不重要——即使你的DSL只是一个包装,比如Swing,它的编译和静态验证要比解释的好得多(并且在运行时失败)。@nickik,Christophe的主要观点是“编写DSL很难(至少对他来说)”. 对于选择高阶函数而不是AST变换来说,这还远远不够,这只是一个迹象,表明他在用完全错误的方式进行转换。实际上,Clojure社区的绝大多数人都做得不对,他们试图实现复杂的单片宏,而不是简单的转换链。@nickik,宏比函数更容易编写。要容易得多。从另一条评论中查看我的示例。如果这对你来说很难,那你就是做错了。宏应该是平凡的。为什么你们,函数式程序员,擅长将问题分解成小的、可理解的函数,但却无法完成真正的sam