Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macros 将Clojure宏用于DSL_Macros_Clojure_Dsl_Higher Order Functions - Fatal编程技术网

Macros 将Clojure宏用于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有多种类型的用户(只想快速完成某

我正在从事一个Clojure项目,我经常发现自己在为DSL编写Clojure宏,但我在看一个Clojure视频,其中讲述了一家公司如何在实际工作中使用Clojure,演讲者说,在实际使用中,他们不为DSL使用宏,他们只使用宏来添加一点语法糖分。这是否意味着我应该使用标准函数编写DSL,然后在最后添加几个宏

更新: 在阅读了对这个问题的各种各样(有趣)的回答后,我意识到答案并不像我最初想的那么明确,原因有很多:

  • 应用程序中有许多不同类型的API(内部、外部)

  • API有多种类型的用户(只想快速完成某件事情的业务用户,Clojure专家)

  • 是否存在隐藏锅炉铭牌代码的宏

  • 我会离开去更深入地思考这个问题,但谢谢你的回答,因为他们给了我很多思考。我还注意到Paul Graham认为与Christophe视频相反,并且认为宏应该是代码库的一大部分(25%):

    是的

    尽可能编写函数。当函数可以执行时,切勿编写宏。如果你写了很多宏,你最终会得到一些更难扩展的东西。例如,宏不能应用或传递

    克里斯托夫·格兰德:(不=DSL宏)

    不要害怕广泛使用宏。如果有疑问,请始终编写宏。函数在实现DSL方面的性能较差-它们将负担转移到运行时上,而宏允许在编译时执行许多重量级计算。试想一下,将嵌入式Prolog实现为解释器函数和将Prolog编译为某种形式的WAM的宏的区别

    不要听那些说“宏不能应用或传递”的人的话,这完全是一个骗局。那些人提倡翻译而不是编译,这简直是荒谬可笑

    关于如何使用宏实现DSL的几个技巧:

    • 分阶段做。定义从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