Clojure宏与C宏有何不同?

Amo*_*kar 12 clojure

我是Clojure的新手.我几个月前开始.我正在努力学习宏.

我最初对Clojure中宏和高阶函数之间的区别感到困惑,因为高阶函数可以接受lambdas并根据任何条件和过滤执行其中一个所需的次数.

所以我在StackOverflow本身上发布了一个关于此问题的简单示例.我从答案中得到了怀疑.

这就是我的理解,

  • 与评估正文的函数不同,宏不会评估所有参数.
  • 宏可以选择使用quote,unquote和splicing语法来评估什么以及不使用什么以及如何将一段代码转换为另一段代码.
  • 然后评估从宏发出的最终代码.

所以我的问题是,它与C中使用的预处理程序指令和宏有什么不同?Lisp/Clojure宏给开发人员带来了什么样的能力,C宏完全缺乏并且经常被广泛使用.

mik*_*era 12

一些值得注意的差异:

  • Clojure宏在Lisp数据结构上运行,而C宏在文本上运行.这种能力是Lisps同源性的结果(即Lisp源代码表示为Lisp数据结构).对于宏观系统来说,同质性并不是绝对必要的,但它确实使它更加方便和自然.
  • 您可以在运行时执行Clojure宏以及编译时间(例如使用eval)
  • Clojure宏是用Clojure编写的.与C预处理器宏形成对比,后者具有各自独立的迷你语言.在编写更复杂的宏时,这是一个很大的优势:您不必在不同语言之间进行心理切换(​​当然,您仍然需要在处理宏时与您想要执行的代码之间在心理上区分要执行的代码.生成宏的输出)
  • Clojure宏是Turing完成的 - 您可以在其中执行任意代码生成.对于标准C预处理器宏来说并非如此,它们在表达复杂代码生成方面的能力有限.编辑:感谢Jeremy提供了一些有趣的黑客的链接,通过这些黑客可以强制C预处理器以完整的方式进行操作.总的来说仍然存在:这些并不是编写通用代码的实用方法.

可以说,宏仍然是Lisps的显着"杀手特征".关于这个主题的一点额外解释,值得一读保罗格雷厄姆的文章" 是什么使得Lisp不同 "

  • 实际上,你可以拥有一个没有同质性的完整宏系统.用于表示代码的数据结构只具有比Lisp数据结构更复杂的形状.例如,参见[Scala宏](http://docs.scala-lang.org/overviews/macros/overview.html). (3认同)

Jer*_*man 5

C 宏是纯文本重写宏。除了它们来自哪里之外,没有什么关于它们的可怕的 C 语言——您可以在任何文本上使用 C 预处理器cpp(1)。因此,使用 C 预处理器很容易生成非 C 形式,而且就 C 本身而言,您经常不得不跳过箍来做相当琐碎的事情。因此,C 宏充满了陷阱

Clojure 宏是使用不同于常规 Clojure 函数的一组规则执行的 Clojure 代码。它们不是接收已评估的参数并返回结果,而是接收未评估的表单并返回一个表单,该表单最终可能会在正常执行过程中进行评估。