是否可以有效地评估 lambda 演算项?

Is it possible to evaluate lambda calculus terms efficiently?

我最近一直在编写很多 lambda 演算程序,我希望我可以 运行 实时编写其中的一些程序。然而,尽管趋势函数范式是基于 lambda 演算和 B 归约法则,但我找不到一个不是玩具的求值器,不是为了提高效率。函数式语言应该很快,但我所知道的那些实际上并不提供对正常形式的访问(参见 Haskell 的惰性求值器、Scheme 的闭包等),所以不要作为 LC 求值器工作。

这让我想知道:是否不可能有效地评估 lambda 演算项,这只是一个历史事故/缺乏兴趣,没有人决定为其创建一个快速评估器,还是我只是遗漏了什么?

有多种评估 lambda 项的方法。根据类型信息是否可用,您可以获得更高效和更安全的评估程序(不需要运行时检查,因为程序已知运行良好)。我将粗略 介绍一些技巧。

大步评价者

与其重复定位 lambda-redexes 并触发它们(这意味着多次遍历项),您可以设计一种算法,通过评估 "big steps".[=18= 中的项来尝试最小化工作量]

例如如果你想要规范化的术语是 t u 那么你规范化 tu 如果 norm t 是一个 lambda 抽象,你触发相应的 redex 并重新启动规范化你刚刚得到的术语。

抽象/虚拟机

现在,您可以使用抽象机完成基本相同的工作,但速度要快得多。这些小型虚拟机具有自己的指令集和缩减规则,您可以用自己喜欢的语言实现这些规则并将 lambda 术语编译为。

历史例子是SECD machine

Danvy et al. 已经表明,众所周知的抽象机可以通过连续传递样式和去功能化的组合从前面提到的评估器中派生出来。

要从抽象机中获取 lambda 项,您需要实施 具体化/回读 函数,根据机器所处的状态构建 lambda 项。 Grégoire and Leroy 说明如何在语言的类型理论是 Coq 的情况下完成这样的事情。

通过评估规范化

评估规范化是利用宿主语言的评估机制来实施另一种语言的规范化过程的做法。

Lambda 抽象变成宿主语言的函数,应用变成宿主语言的应用,等等

此技术可以以类型化的方式使用(例如,将简单类型化的 lambda 演算标准化 in Haskell or in OCaml) or an untyped one (e.g. the simply-typed lambda-calculus once more or Coq terms 编译为 OCaml (!))。

就目前的知识水平而言,评估 lambda 项的最佳方法是所谓的最优图缩减技术。 1989 年,J.Lamping 在他的 POPL 文章“An algorithm for optimal lambda calculus reduction", and then revised and improved by several authors. You may find a survey in my book with S.Guerrini "The optimal implementation of functional programming languages”(剑桥理论计算机科学丛书第 45 期,1998 年)中介绍了该技术。

术语"optimal"指的是共享管理。在 lambda 演算中,你有很多重复,减少的效率至关重要 基于避免重复工作。在一阶设置中,有向无环 图(dags)足以管理共享,但是一旦进入更高阶设置,您就需要更复杂的图结构,包括 共享和取消共享。

就纯 lambda 术语而言,最佳图缩减比所有其他已知的都快 减少技术(环境机器、超级组合器或其他)。 上面的书中给出了一些基准(参见第 296-301 页),我们在其中 证明我们的实施优于 caml-light(前体 ocaml) 和 Haskell (真的很慢)。 所以,如果你听到人们说它从未被证明是最优的 减少比其他技术更快,这是不正确的:两者都被证明 在理论上和实验上。

函数式语言尚未以这种方式实现的原因是 在函数式编程的实践中,你很少使用函数式 排名非常高,当你这样做时,它们通常是线性的。 一旦你提高等级,lambda 的内在复杂性 条件可能变得危险地高。有一种技术可以让你 及时减少一项 O(2^n) 而不是 O(2^(2^n)) 并不能使所有 这种差异,在实践中:两种计算都是不可行的。

我最近写了一篇短文试图解释这些问题: “About the efficient reduction of lambda terms”。 在同一篇文章中,我还讨论了超优的可能性 还原技术。