7

我已经阅读了 SICP 的第 4 章,发现第一节列出了实现评估器最重要的功能,eval并且apply,我知道这eval很重要,但为什么apply这么重要?对于某些语言,在 Javascript 中完全没有apply这样的语言。

编辑:对不起,我错了,在 Javascript 中没有应用,请忽略它。

4

3 回答 3

8

SICP(和其他地方)中的 eval/apply 将评估器的两个主要部分分开。第一部分,即eval正在做的部分,是处理将代码的语法翻译成它的含义——但除了对表达式类型进行分派之外,它几乎什么都不做。正如您在书中看到的那样,eval-foo各种“特殊形式”有各种不同的 s,因为它们中的每一个都有自己独特的评估规则。

现在,评估者需要处理的最重要的形式是函数应用。事实上,这个表单没有关键字非常重要(否则,您会看到apply或任何乱扔垃圾的方案/lisp 代码)。相反,如果一个表单以不是已知的特殊形式(在实际实现中,不是已知的宏)开头的东西,那么评估器会将其视为一个函数应用程序。此时,要评估函数调用,您需要评估函数本身(第一种形式)及其所有参数,然后需要第一个值应用于其余部分。eval这里的一个主要启蒙时刻是意识到这和前者之间存在重大区别apply——前者本质上是处理语法的,但后者处理

附带说明一下,一些人将此与 Scheme 和 Lisp 实现所具有的内置apply函数相混淆。为什么该函数需要使用语言与 SICP 点完全无关(粗略地说,它提供了没有它就无法实现的功能,它是从实现到语言的一种反射形式)。我什至认为 SICP 评估人员甚至不apply提供解释性语言。如果您正在寻找更多启发,那么这样做(使用 SICP 元循环评估器,并添加apply解释语言中)将是一个很好的反思练习。

于 2011-06-07T17:22:18.200 回答
2

这是您在表达式上运行函数的方式,也就是将函数“应用”到表达式。

注意这里的代码:

http://mitpress.mit.edu/sicp/code/ch4-mceval.scm(死链接)

于 2011-06-07T16:14:23.737 回答
1

Apply 评估函数调用。它需要一个函数和一个参数列表:(apply fn args). 如果你有一种支持函数调用的语言,你的解释器中可能会有一个 apply 函数。Scheme 和 Javascript 之间的区别在于,Scheme 不仅将这个函数暴露给解释器,还暴露给正在解释的程序。

于 2011-06-07T16:20:01.370 回答