宏,clojure与普通lisp

时间:2012-03-08 01:42:59

标签: macros clojure common-lisp

我的一些朋友和我正在开发一个新平台,我们希望在lisp中构建它。主要的吸引力是宏。我们都使用Common Lisp,但我想探索Clojure的选项。

当我提出这一点时,其中一人说宏观系统“较弱”。我想知道这是否属实,以及在哪些方面。

5 个答案:

答案 0 :(得分:25)

就你可以用它们做什么而言它们几乎相同,即:

  • 他们在编译时执行
  • 他们可以执行任意转换和生成代码(利用homoiconicity的Lisp代码)
  • 它们适合用新语言结构或DSL“扩展语言”
  • 你感觉非常强大,而且效率很高(beating the averages方式)

现在有些不同之处:

Common Lisp还允许 reader宏,它允许您更改阅读器的行为。这允许您引入全新的语法(例如,用于数据结构文字)。这可能是你的朋友将Clojure的宏系统描述为“较弱”的原因,因为Clojure不允许读者宏。在Clojure中,你基本上坚持语法(macro-name ....)但除此之外你可以做任何你想做的事情。关于读者宏是否是好事的意见分歧:我的个人观点不是,因为它没有给你任何额外的“力量”,并且有可能引起极度混乱。

在我看来,Clojure有一个更好的命名空间实现,我认为让Clojure的宏系统更容易使用。 Clojure中的每个符号都是名称空间限定的,因此不同的库可以在它们自己的名称空间中定义不同的相同符号。因此,+可以单独定义为clojure.core/+ and my.vector.library/+,不存在任何冲突风险。在您自己的命名空间中,您可以use来自其他命名空间的定义,这意味着您可以根据需要选择+clojure.core中的my.vector.library

另一方面,Clojure对于地图{}和向量[]具有额外文字。与传统的Lisp s表达式相比,它们使您的表达能力更强(在简洁的可读语法意义上)。特别是,对于绑定表单使用[]是Clojure中的一种惯例,我认为它对宏和普通代码都很有效 - 它使它们从其他括号中清楚地脱颖而出。

Clojure也是一个 Lisp-1 (比如Scheme),所以它没有单独的函数和数据命名空间。 Common Lisp是一个 Lisp-2 ,它有独立的函数和数据名称(因此你可以同时拥有一个名为foo的函数和一个名为foo的数据项)。我稍微喜欢Lisp-1方法,因为它更简单,当你在函数语言中编写时,代码和数据之间的划分似乎有点武断。这可能是个人品味的事情。

总体而言,差异相对较小。我认为Clojure更简单,更优雅,而Common Lisp有一些额外的功能(使用风险自负!)。两者都非常有能力,所以你也不能选错。

答案 1 :(得分:12)

关于普通宏,这里是Lisp和Clojure变体之间的区别:

  1. Clojure Lisp-1 ,而CL Lisp-2 。历史表明,一个命名空间语言中的宏通常更容易出错,因为有更大的名称冲突机会。为了缓解这个问题,Clojure使用了非传统的准报价实现。
  2. 但它需要付出代价:因为在Clojure中,反引号内的符号在命名空间中得到了热切的解决,其中定义了宏,所以存在许多微妙的问题,例如this one
  3. Clojure宏使用自动gensyms。这被宣传为一个优点,它确实删除了一些样板(当然,你可以在Lisp中实现相同 - 见defmacro!)。显然,关于何时使用gensyms的概念性问题仍然存在。
  4. 总的来说,Lisp的方法更粗糙,但更灵活。当你超越简单的语法修改并开始定义完整的DSL时,Clojure的宏可能会更容易接近,但会变得更难使用。

    关于读者宏,如您所知,Clojure不会向用户提供此选项,而CL会这样做。因此,在CL阅读器中,宏找到了很多用途,例如string interpolationinternationalization supportSQL DSLsjava interop。更不用说过多的特殊情况,当读者宏可用于帮助创建高级DSL时。

答案 2 :(得分:4)

我是80年代lisp机器上的lisp程序员。在生产力方面,我仍然需要看到类似的开发环境。也就是说,clojure宏系统足够强大,已经被滥用。当您必须实现新语言的“编译器”并且您应该能够以正式表示法描述宏时,宏会有所帮助。不是因为你绝对需要。新语言本身的用户需要它。所以,它应该是一个非常有用的形式语言,应该得到一个编译器和一个正式的符号。如果不是这样,请远离宏并使用纯函数式编程样式来进行抽象。您会再次感受到使用模拟顺序编码的乐趣,而不是更接近于哑位序列。而且您的代码用户也会更快乐。我希望clojure宏滥用不会成为下一个意外的复杂性。一个老lisper和clojure的新手。

答案 3 :(得分:1)

可能是你的朋友指的是Clojure宏系统是“弱”的,因为Clojure目前不支持“读者宏”,但这并不意味着宏系统较弱,因为读者宏可以制作就我对使用它们的理解而言,事情真的非常复杂。

我也不会建议您将宏视为主要吸引力。它们很强大但是当你被一些特定的技术所吸引时,你开始在任何地方应用它,即使有一个更简单的技术可用(在宏观情况下,更简单的技术是函数)。

您应该考虑的另一个重要事项是您希望定位的“平台”,因为Clojure支持JVM以及JVM平台的所有工具。

答案 4 :(得分:1)

Clojure Macros有一些优势:

  • 意外符号捕获很难,因为它命名空间扩展了符号
  • 其他人的读者宏不会咬你(不是你的或当然,我在谈论那个人;))
  • autogensyms在编写hygenic宏时带来了很多混乱。