2

布赖恩在他对“副作用是好事吗?”这个问题的论证中的前提。很有趣:

计算机是 von-Neumann 机器,旨在与效果很好地配合使用(而不是设计为与 lambda 配合使用)

我对这些方法的并置感到困惑。我不能把它们看成黑白的。什么是证明价值:

计算机是 von-Neumann 机器,旨在与效果一起工作 [1]

最后一部分让我感到困惑:

而不是被设计为与 lambdas [2] 一起工作

Lambda 是否用作函数式编程的符号?还是它们是函数式编程的委婉说法?真正的讯息是什么?

在什么意义上,前提 [1] 和 [2] 的部分是正确的?回复中隐藏的前提是什么?有人可以证明最初的前提吗?冯诺依曼机器和 Lambda 是如何真正工作的?

4

2 回答 2

6

这是的意思更深入的内容,尽管看看其他人是否同意或他们必须说什么会很有趣。

想想今天的计算机是如何工作的。您拥有具有整数和浮点寄存器的硬件,以及大量随机存取存储器,以及主要形式为“基于读取此寄存器/存储单元的值,将这个新值插入此寄存器的指令” /细胞'。(当涉及到高速缓存行和一致性以及内存模型等等时,更新内存单元具有各种性能影响。)整数是 32 位或 64 位,几乎所有编程语言都显示这些与硬件完全匹配的数据类型。几乎每个运行时都使用一个小的调用堆栈,其中堆栈分配的对象很便宜,以及一个更昂贵的“堆”,当需要非基于堆栈的生命周期时,可以在其中创建和销毁其他对象。

现在考虑大多数现代函数式编程语言。不变性是常态;您很少会用新值“戳”内存。(这意味着你创造了更多新的对象,这意味着您分配了更多。) Lambda 和延续是常态;您很少有与堆栈相对应的对象生命周期。(事实上​​,一些 FP 运行时不使用堆栈;在 CPS 实现中,堆栈和程序计数器的概念是不合时宜的。)递归是一个循环结构,因此您至少需要“尾”调用来不消耗反正堆栈。几乎所有东西都需要“堆”分配,当然你需要一个垃圾收集器。代数数据类型提供标记数据;理论上,这些标签只需要额外的 2 或 3 位数据,但为了匹配运行时,它们通常需要额外的内存字或更多。...我有点曲折,但你最常用FP 语言做的事情往往与那些事情完全对应在典型的计算机硬件架构和基本语言运行时上扩展最差最昂贵。

不一定要那样。可以想象一个运行时避开堆栈并快速进行堆/分配(而不是多线程应用程序的瓶颈)的世界。可以想象这样一个世界,其中可互操作的整数类型有 29 位或 60 位,而运行时/硬件使用单词的额外剩余位,例如 GC、代数类型标签或诸如此类。(我认为一些 FP 实现/运行时会做一些这些技巧。)等等等等......关键是,如果你将现代函数式语言作为给定的,然后围绕它设计运行时/硬件,它看起来会非常不同从今天的典型硬件/运行时。

(我不认为我沟通得那么好,而且我对许多我不确切知道的细节不精确,但希望你能在这里理解我论文的要点。)

于 2009-04-19T00:14:50.300 回答
3

我不完全确定你在问什么,但是当我读到它时,你在问他所说的 lambdas 是什么意思?

他指的是lambda 演算,它构成了函数式编程的大部分理论基础。它是(除其他外)描述和推理高阶函数的抽象符号。

冯诺依曼机器基本上就是我们所拥有的。程序由操作和访问存储(我们的 RAM)的指令执行。也就是说,一切都是通过副作用隐式完成的。数据从 RAM 中的某个区域读取,经过一些处理,然后写回 RAM 中的某个(可能是其他)区域。在没有副作用的情况下,CPU 将被限制在上电时处理其寄存器中碰巧出现的任何垃圾数据。

Lambda 演算没有副作用的概念,因此基于此原理的机器不会区分“CPU 可以访问的内容”(本质上是我们的寄存器)和“可以间接访问的内容”(我们的 RAM)。这样一台机器中的一切都将基于函数原理,即函数接受一个或多个参数,并返回一个新值,从不修改现有值。(不,我不确定这在硬件中如何工作...... :))

这是否回答你的问题?

于 2009-04-18T23:05:23.507 回答