【问题标题】:What is the relationship between static typing and lazy functional languages? [closed]静态类型和惰性函数语言之间有什么关系? [关闭]
【发布时间】:2012-10-06 01:32:09
【问题描述】:

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

特别是,Lazy 评估中的Wikipedia article 内容如下:

但是,懒惰的评估,很难与 命令性功能,例如异常处理和输入/输出, 因为操作的顺序变得不确定。懒惰的评价 可能会导致空间泄漏。

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

【问题讨论】:

  • 这两件事之间没有关系。懒惰是关于when to evaluate 而静态类型是关于给编译器一些关于你的代码的extra information
  • @Ankur 这些是离散概念的事实并不意味着在这种情况下它们之间没有关系。提问者在问“惰性”函数式语言的本质是否使静态类型特别有利(反之亦然,也许)。考虑到这两个特征之间可观察到的对应关系,这是一个非常合理的问题。
  • ML 系列语言怎么样,Josh?默认情况下,它们是静态类型和渴望的,惰性只能通过闭包作为选项提供。不过,这不会使您的观点无效;)
  • SASL 是 David Turner 在 Miranda 家族中的第一个语言,它似乎是无类型的(与静态类型相反),令人惊讶的是,它可能是 St Andrews 静态语言。我相信 Nyquist - Roger Dannenberg 的声音合成语言 - 很懒惰,看起来不是很打字。

标签: haskell types functional-programming scheme lazy-evaluation


【解决方案1】:

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

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

【讨论】:

  • 这很有趣,所以像 Haskell 这样的语言通过静态类型来防止无意的副作用?
  • Haskell 通过没有任何副作用原语来防止无意的副作用(名称以unsafe 开头的东西除外,但它们不算在内)。存在允许效果但限制效果的类型系统,但 Haskell 的方法更简单。
  • (当然,在 Haskell 中,由于 IO monad,实际上可以打印东西并发射导弹等。您可以将其视为使用类型控制效果的问题;我看它只是在一个缺乏效果的系统中模拟效果。)
  • 我不得不承认,看到这被接受为主要答案,我有点失望。它只回答了一个很好的问题,在我看来,不是最有趣的问题。无意冒犯保罗;我只是希望看到更多种类的分析器。
  • @itsbruce 我读到标题和两个以问号结尾的句子都在问同样的事情;你能帮忙重述你更感兴趣的问题吗?
【解决方案2】:

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

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

例如区域类型和其他效果类型。

【讨论】:

  • 您能引用任何详细解释这一点的参考资料吗?否则,这实际上只是一个声明(尽管如此),并没有给提问者很多帮助。
  • 另外,我不太明白你的意思。对象的生命周期与静态类型有什么关系?您甚至可以在 C++ 中实现动态类型,并且仍然拥有完整的 RAII(类似于 std::unique_ptr<Object>)。
  • @itsbruce :您可以查看disciple.ouroborus.net 以了解以这种方式使用区域的类型系统。
  • @ChrisKuklewicz:感谢您的链接。
【解决方案3】:

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

  1. 无类型
  2. 键入
    • 惰性求值 Haskell 就是一个例子。
    • 急切评估 OCaml 就是一个例子。

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

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

如果一个项 M 简化为 N 并且 M:σM 类型σ) 然后 N:σ.

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


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

  1. 命令式功能。这与打字系统无关。问题是,如果评估某些表达式在惰性设置中具有副作用(如大多数语言中的 I/O),则很难预测何时(如果有的话)会发生副作用。因此,一旦你有了惰性求值,就几乎不可能有不纯的语言。

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

  2. 空间泄漏。这是惰性求值的一个已知缺点。请参阅 Real World Haskell 中的 Building up unevaluated expressionsCh. 25 Profiling and optimization。但这又与类型系统无关——你会在无类型语言中得到相同的行为。

【讨论】:

    【解决方案4】:

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

    懒惰评估的意义何在?

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

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

    对于他通过惰性计算重用函数的示例,Augustsson 提供了“通过重用 mapor 函数来表达 any 函数是很自然的。”太懒了从这张图片中可以看出,评估是一种成本相当高的语言功能,为更自然的编码风格服务。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-26
      • 2011-02-11
      • 1970-01-01
      • 1970-01-01
      • 2023-03-20
      • 2015-10-24
      相关资源
      最近更新 更多