programming-languages - 懒惰作为内置语言功能的实际用途是什么?

标签 programming-languages functional-programming language-design lazy-evaluation

很明显,为什么想要变得懒惰的函数式编程语言需要是纯的。我在看相反的问题:如果一种语言想要纯粹,那么懒惰是否有很大的优势? Haskell 的一位设计者提出的一个论点是,它消除了诱惑;也许吧,但我正在努力权衡更具体的优势。

考虑到您想做函数式编程,在哪些用例中,内置懒惰可以让您更清晰、简单或简洁地表达事物?

简单地说:为什么懒惰如此重要以至于您想将其构建到语言中?

(我正在寻找更面向应用程序而不是演示的用例 - 我知道你可以通过过滤自然数的无限列表来生成无限的素数列表,但是谁在午餐前写了十次...)

最佳答案

“除非在另一个地方需要它,否则不会评估任何东西”是一个简化的比喻,它没有涵盖惰性评估的所有方面(例如,它没有提到严格现象)。

从理论的角度来看,在设计纯语言时有 3 种方法(当然,如果它基于某种 lambda 演算而不是更奇特的评估模型):严格、非严格和完全。

它们每个都有其优点和缺点,因此您需要阅读相应的研究论文。

总语言是三者中最纯粹的。在另外两个中,非终止可以被视为副作用,因此必须构建严格性和总体分析器以保持实现高效。两种分析都是不可判定的,因此分析器永远不可能是完整的。

然而,总语言的表达能力最低:总语言不可能是图灵完备的。获得足够好的表达能力的一种常用方法是为有根据的递归建立一个内置的证明系统,这并不比非总语言的分析器更容易构建。

从实用的角度来看,非严格语义让您可以更轻松地定义控制抽象,因为控制结构本质上是非严格的。在严格的语言中,您仍然需要一些具有非严格语义的地方。例如。 if即使在严格的语言中,construct 也具有非严格的语义。

因此,如果您的语言很严格,则控制结构是一种特殊情况。相比之下,非严格语言可以是统一非严格的——它没有严格结构的内在需求。

至于“谁在午餐前写了十次” - 任何使用 Haskell 进行项目的人都会这样做。我认为使用一种语言(在您的情况下是一种非严格的语言)开发一个非玩具项目是了解其优缺点的最佳方式。

以下是一些非玩具示例说明的懒惰的通用用例:

  • 控制流难以预测的情况。当没有惰性时,您必须对属性执行拓扑排序以解决依赖关系,请考虑属性语法。每次更改依赖关系图时重新排序代码是不切实际的。在 Haskell 中,您可以在没有显式排序的情况下实现属性语法形式,并且在 Hackage 上至少有两个实际实现。属性文法在编译器构造中有广泛的应用。
  • 解决许多优化问题的“生成和搜索”方法。在严格的语言中,您必须交错生成和搜索,在 Haskell 中,您只需组合单独的生成和搜索函数,您的代码在语法上保持模块化,但在运行时交错。想想旅行商问题 (TSP),当您生成所有可能的旅行,然后使用分支定界算法搜索它们时。请注意,分支边界算法仅检查旅行的某些第一个城市,仅生成路线的必要部分。即使在最纯粹的配方中,TSP 也有多种应用,例如规划、物流和微芯片制造。稍加修改后,它在许多领域(例如 DNA 测序)中似乎是一个子问题。
  • 惰性代码具有非模块化的控制流,因此单个函数可以根据它执行的环境有许多可能的控制流。这种现象可以看作是某种“控制流多态性”,因此惰性控制流抽象更通用与严格的对应物相比,高阶函数的标准库在惰性语言中更有用。想想 Python 生成器、循环和列表迭代器:在 Haskell 中,列表函数涵盖了所有三个用例,由于懒惰,控制流适应不同的使用场景。它不限于列表——想想 Data.Arrow 和 iteratees,State monad 的惰性和严格版本等。还要注意,非模块化控制流既是优点也是缺点,因为它使性能推理变得更加困难。
  • 惰性可能无限的数据结构除了玩具示例之外还非常有用。请参阅 Conal Elliott 关于使用尝试内存高阶函数的作品。无限数据结构表现为无限搜索空间(参见 2)、无限循环和 Python 意义上的永不耗尽的生成器(参见 3)。
  • 关于programming-languages - 懒惰作为内置语言功能的实际用途是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8279781/

    相关文章:

    web - Elm 将 onInput 与数字一起使用

    functional-programming - 为什么引发异常是副作用?

    c# - C# 平台是中立的吗?

    java - 支持/整合语言测量单位的策略是什么?

    multithreading - 混合线程模型(M :N) Implementation

    programming-languages - "Hello World"在以 Q、U 和 Y 开头的语言中

    c# - int、string、array、list、object 等的公认命名约定是什么

    java - java 8 中 lambda 表达式的副作用

    programming-languages - `occs` 应该可供程序员使用吗?

    excel - VBA 代码可以在 MS 应用程序之外运行吗?