9

我很好奇静态类型和惰性函数语言之间的关系。例如,是否有可能拥有动态的惰性函数式语言?似乎所有的惰性函数式语言都是静态类型的(Haskell、Miranda 等),而所有动态函数式语言都使用严格的评估(Clojure、Scheme 等)。

特别是,关于懒惰评估的维基百科文章写道:

但是,使用惰性求值时,很难与异常处理和输入/输出等命令式特性结合起来,因为操作的顺序变得不确定。惰性求值会引入空间泄漏。

静态类型在防止空间泄漏方面起什么作用?

4

4 回答 4

14

我根本不相信静态类型起作用。例如,考虑无类型的惰性语言Lazy Racket。我没有听到任何迹象表明它以 Haskell(例如)没有的方式泄漏空间。

另一方面,副作用一个问题,因为人类发现严格评估的评估顺序是(相对)自然的,而按需调用更难在心理上预测。

于 2012-10-16T03:17:09.983 回答
6

静态类型在防止空间泄漏方面起什么作用?

类型可用于跟踪对象的生命周期,静态确保不存在泄漏。

一个例子是区域类型和其他效果类型。

于 2012-10-16T04:52:43.727 回答
3

惰性求值和静态类型是独立的概念。

  1. 无类型
  2. 打字
    • 惰性求值Haskell 就是一个例子。
    • 渴望评估OCaml 就是一个例子。

粗略地说,评估是在程序运行时发生的事情。键入是在编译程序时发生的事情。

但是,打字系统和评估策略之间当然存在重要的对应关系:

如果项M简化为NM:σM属于σ类型),则N:σ

这意味着当我们运行具有某种类型σ的程序时,该值将具有相同的类型。没有这个属性,打字系统就真的没用了(至少对于编程来说)。这也意味着一旦我们在编译过程中键入了一个程序,我们在评估它时就不需要记住键入信息,因为我们知道结果将具有正确的类型。


关于您引用的维基百科文章。有两种不同的东西:

  1. 势在必行的特征。这与打字系统无关。问题是,如果评估某些表达式在惰性设置中具有副作用(如大多数语言中的 I/O),则很难预测何时(如果有的话)会出现副作用。因此,一旦您进行了惰性评估,就几乎不可能拥有不纯的语言。

    一个例外是Clean语言。它使用一种特殊的类型系统来处理惰性设置中的副作用。所以这里通过处理副作用在评估策略和类型系统之间存在一些联系:类型系统允许以我们可以保持惰性评估的方式处理副作用。

  2. 空间泄漏。这是惰性求值的一个已知缺点。请参阅构建未计算的表达式Ch. 25 Real World Haskell 中的分析和优化。但这又与类型系统无关——你会在无类型语言中得到相同的行为。
于 2012-11-17T11:55:40.857 回答
2

我认为,如果您从更一般的角度来看事物,则可以观察到静态类型和惰性函数式语言之间的自然关系。静态类型的主要目的是通知和提升编译器的功能;调查语言之间的静态-动态划分,它通常跟踪编译代码和解释代码之间的分裂。

懒惰的评估有什么意义?

Peyton-Jones 等人的一篇臭名昭著的回顾性文章将惰性评估描述为“头发衬衫”,它使语言保持纯粹的功能性。他的比喻恰如其分地传达了 Haskell 社区根深蒂固的指称语义理想主义。非严格评估的基本好处是它以促进这种指称范式的方式改变了构建代码的可能性。在 Bob Harper 和 Haskell 社区进行的臭名昭著的惰性评估辩论中,Harper 教授展示了惰性评估给实际程序带来的挑战——在 Lennart Augustsson 对惰性的辩护中,这一点最能说明这一点:

“我把我对严格评估的最大抱怨留到了最后。严格评估在函数重用方面存在根本缺陷。[...] 有了严格的评估,你不能再板着脸告诉人们:不要使用递归,重用map、filter、foldr 等中的递归模式。它根本不起作用(一般来说)。[...] 严格的评估真的,从根本上阻止了你以你可以懒惰的方式重用函数。

对于他通过惰性求值实现函数重用的示例,Augustsson 提出,“通过重用and函数来表达函数是很自然的。anymapor ”因此,惰性求值从这张图片中出现,作为一种成本相当高的语言特性,被包含在一种更自然的风格中的编码。

我们还需要什么来维持一种抽象的、指称的编码风格?一个强大的优化编译器可能会派上用场!因此,即使静态类型和惰性求值之间没有技术或必要的联系,这两个特性也是面向同一个目标的。他们经常一起出现并不奇怪。

于 2012-11-17T02:28:42.913 回答