【问题标题】:Why is it harder to add macros to Haskell than to Scheme为什么将宏添加到 Haskell 比添加到 Scheme 更难
【发布时间】:2018-06-18 17:01:32
【问题描述】:

显然向 Haskell 添加宏比在 Scheme 中更难。

我对函数式编程中的宏到底是什么感到非常困惑,但根据我对 C 语言的理解,它是在预处理时改变“代码”的代码,而不是程序本身。

这是否与 Haskell 是纯的这一事实有关,因此更改函数式代码要困难得多?

跟惰性求值有关系吗?

【问题讨论】:

  • 这是否与 Haskell 是纯的,因此更难更改函数式代码这一事实有关? 不是:宏在代码之间大多是纯函数。
  • Scheme/Lisp 宏的名称与 C 预处理器宏相同。

标签: haskell functional-programming macros scheme


【解决方案1】:

恰恰相反,这与 Haskell 的纯粹或懒惰毫无关系。

宏在 Haskell 中不常见的主要原因是它是一种静态的编译语言,因此无论如何在运行时 更改代码都是不可能的。此外,它没有 Lisps 那样简单的语法,所以编写编译时宏总是有点麻烦。

http://hackage.haskell.org/package/template-haskell-2.12.0.0/docs/Language-Haskell-TH.html#t:Exp

Haskell 的惰性求值及其强类型系统的抽象能力意味着,在许多 Scheme 程序员会使用宏的情况下,您根本不需要 宏。基本上,你可以抽象出计算本身的概念,这很像宏(如果你问我,那就更酷了......)。

【讨论】:

  • 当然,我同意惰性和纯洁性并不重要,Scheme 更简单的语法确实重要。不过,我真的不明白这与静态或编译有什么关系:宏通常不会在运行时生成代码。
  • 方案本身已经发展为更适合编译。 R5RS eval 很弱。球拍已上演进口。人们使用apply 的次数不多。
  • 我不会反对,但该语言的静态和编译性质与宏无关。 Racket 是静态编译的,拥有极其丰富的宏系统。
  • @JohnClements 我没怎么用过 Racket,但我记得它原则上感觉与其他 Lisps 没有什么不同,动态 types 促进了代码作为-数据方法。现代 Lisp 方言能够进行大量预编译并且对其余大部分进行 JIT 优化这一事实很棒,但是 IMO 并没有改变这些语言至少是概念解释语言的事实,而 Haskell 故意非常编译时间和运行时间之间的明确界限。
  • 是的,Racket 是动态的,但它的宏系统具有非常静态的味道。这是非常有意的——它允许更好的编译。作为一个整体,Racket 倾向于尽最大努力防止昂贵的动态特性减慢不使用它们的代码。
【解决方案2】:

This should help you。 Lisp 语言的语法比其他语言简单得多,并且解析器可以直接从该语言访问。

Clojure 是一种既懒惰又可以处理纯代码但仍具有 Lisp 强大的宏的 lisp。

【讨论】:

    【解决方案3】:

    除了之前的答案,我想说 Haskell 和 Scheme 都主要是学术语言,这意味着对它们的工作是由研究人员和他们的特殊兴趣驱动的。对于这些语言,那些对宏感兴趣的人可能会倾向于使用语法系统(Scheme/Racket/Clojure)的语言,其统一性(所有内容都加括号)使得宏定义变得非常容易。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-29
      • 1970-01-01
      • 2019-07-13
      • 2012-03-27
      • 1970-01-01
      • 2016-01-18
      相关资源
      最近更新 更多