我最近在lambda演算中编写了很多程序,我希望我可以实时运行其中的一些程序。然而,尽管趋势功能范例基于lambda演算和B减少规则,但我找不到一个不是玩具的单一评估者,而不是效率。功能语言应该很快,但我知道的那些实际上并不提供对普通表单的访问(参见Haskell的惰性求值程序,Scheme的闭包等),所以不要用作LC求值器。
这让我想知道:只是不可能有效地评估lambda演算术语,它只是一个历史事故/缺乏兴趣,没有人决定为它创建一个快速评估者,或者我只是遗漏了什么?
答案 0 :(得分:13)
在目前的知识水平下,评估λ项的最佳方法是所谓的最优图减少技术。该技术于1989年由J.Lamping在他的POPL文章“An algorithm for optimal lambda calculus reduction”中引入,然后由几位作者修改和改进。您可以在我的书中找到S.Guerrini“The optimal implementation of functional programming languages”,剑桥理论计算机科学杂志,第44页,1998年。
“最优”一词指的是共享管理。在lambda演算中,你有很多重复,减少的效率是至关重要的 基于avoding复制工作。在第一顺序设置中,有向无环 图表(dags)足以管理共享,但只要您输入更高阶的设置,就需要更复杂的图形结构 分享和取消共享。
在纯lambda术语上,最佳图形缩减比所有其他已知的更快 减少技术(环境机器,超级组合器或其他)。 上面的书中给出了一些基准(参见第296-301页) 证明我们的实施优于两种光源(前驱体) ocaml)和Haskell(非常慢)。 所以,如果你听到人们说它从未被证明是最佳的 减少比其他技术更快,但事实并非如此:事实证明两者兼而有之 在理论和实验上。
功能语言尚未以这种方式实现的原因是 在函数式编程的实践中,你很少使用函数 排名非常高,当你这样做时,他们经常是线性的。 一旦你提高了等级,lambda的内在复杂性 术语可能会变得非常危险。有一种技术可以让你 减少一个时间段O(2 ^ n)而不是O(2 ^(2 ^ n))并不能全部 在实践中这种差异:两种计算都是不可行的。
我最近写了一篇试图解释这些问题的简短文章: “About the efficient reduction of lambda terms”。 在同一篇文章中,我还讨论了超优化的可能性 减少技术。
答案 1 :(得分:9)
评估lambda术语有多种方法。根据类型信息是否可用,您可以获得更高效和更安全的评估程序(不需要运行时检查,因为已知程序运行良好)。我将给出一些粗略的介绍一些技巧。
不是重复定位lambda-redex并触发它们(这意味着多次遍历这个术语),你可以设计一种算法,试图通过在“大步骤”中评估一个术语来最小化工作。
E.g。如果要标准化的术语是t u
,那么您将t
和u
标准化,如果norm t
是lambda抽象,则触发相应的redex并重新开始标准化你得到的这个词。
现在,您可以使用抽象机器完成相同的工作但速度更快。这些小型虚拟机具有自己的一套指令和简化规则,您可以用自己喜欢的语言实现这些规则并将lambda术语编译为。
历史示例是SECD machine。
Danvy et al.已经表明,众所周知的抽象机器可以通过连续传递风格和去功能化的组合从前面提到的评估器中派生出来。
要从抽象机器中获取lambda-term,您需要实现 reification / read back 函数,根据机器所处的状态构建lambda术语。Grégoire and Leroy展示如何在语言的类型理论是Coq。
的语境中完成这样的事情评估规范化是利用宿主语言评估机制实现另一种语言规范化程序的做法。
Lambda抽象转换为主机语言中的函数,应用程序变为主机语言的应用程序等等。
这种技术可以以类型化的方式使用(例如,简化类型的lambda-calculus in Haskell或in OCaml)或无类型的(例如简单类型的lambda-calculus {{3) }或once more编译为OCaml(!))。