哪种 FP 语言在代码外观、感觉和行为上与 lambda 演算抽象最接近?
2 回答
这可能不是一个真正的答案,它更多的是对你真正想要什么的猜测。
一般来说,lambda 演算中几乎没有什么——你基本上需要(一等)函数、函数应用程序和变量。这些天来,您将很难找到一种不为您提供这些东西的语言……但是,当您尝试学习它时,事情可能会变得混乱-例如,仅使用纯数字就很容易然后把它们和教堂数字混在一起。(我已经看到很多学生都发生过这种情况,适应这种材料所需的正式思维已经够难了,以至于将编码扔到一堆并没有真正帮助......)
正如 Don 所说,Scheme 非常接近于“普通”的无类型 lambda 演算,如果您正在阅读 The Little Schemer,它可能非常适合您的情况。如果你真的想使用“正确”的 LC,你需要确保你只使用函数(问题如上);但是您会遇到一些额外的问题,尤其是当您阅读有关该主题的各种其他文本时。首先,大多数文本将使用您在 Scheme 中没有的惰性求值。其次,由于 LC 只有一元函数,因此缩短术语并使用例如λxyz.zxy
代替“真实”形式(在这种情况下是λx.(λy.(λz.((z x) y)))
或(lambda (x) (lambda (y) (lambda (z) ((z x) y))))
在 Scheme 中)是很常见的。(这称为柯里化。)
所以是的,Scheme 非常接近 LC,但对于所有这些问题来说,这并没有什么意义。Haskell 可以说是一个更好的候选者,因为它既懒惰,又对函数的多个参数进行这种柯里化。OTOH,你正在处理一种类型化的语言,这是一个相当大的包袱带入这个游戏——如果你尝试做 TLS 风格的例子,你会陷入一些严重的泥潭......
如果你确实想要得到所有东西(懒惰、速记、无类型、足够接近 Scheme),那么Racket还有一点需要考虑。在高层次上,它非常接近 Scheme,但它更进一步,因为您可以快速推出一种将 Racket 语言限制为仅lambda
表达式和函数应用程序的语言。做更多的工作,你也可以让它做咖喱,你甚至可以让它变得懒惰。这不是你现在应该尝试自己做的练习——但如果这听起来像你想要的,那么我可以给你指点我的课程(在课堂笔记中寻找“Schlac”),我们使用的语言正在执行上述所有操作,并且受到极大限制,因此您得到的只是基本的 LC 构造。(例如,3
在你定义它之前是一个未绑定的标识符。)请注意,这不是一些解释器——它被编译成 Racket 代码,这意味着它运行得足够快,你甚至可以编写使用数字的代码。你也可以在那里获得该语言的实现,一旦你安装了它,如果你以#lang pl schlac
.
Lambda 演算是一个非常非常受限的编程模型。你只有功能。没有文字,没有内置的算术运算符,没有数据结构。一切都被编码为函数。因此,大多数函数式语言都试图以更方便日常编程的方式扩展 lambda 演算。
Haskell 使用 lambda 演算的现代扩展作为其核心语言:System F,扩展了数据类型。(GHC 已将其进一步扩展到System Fc,支持类型平等强制)。
由于所有 Haskell 都可以直接用其核心语言编写,并且其核心语言是类型化 lambda 演算(特别是二阶 lambda 演算)的扩展,因此可以说 Haskell 紧密遵循 lambda 演算,取模其内置的并发运算符; 并行性;和记忆副作用(和 FFI)。这使得新编译器优化的开发变得更加容易,也使得给定程序的语义更易于理解。
另一方面,Scheme 是无类型 lambda 演算的变体,扩展了副作用和其他非 lambda 演算概念(例如并发原语)。可以说紧跟无类型 lambda 演算。
唯一重要的人是:学习 lambda 演算的人;和编译器作者。