我已经阅读了SICP的第4章,并且发现第一部分列出了实现评估者eval
和apply
最重要的功能,我知道eval
非常重要,但为什么apply
如此重要?对于某些语言,Javascript中完全没有apply
。
编辑:抱歉,我错了Javascript中没有申请,请忽略它。
答案 0 :(得分:6)
SICP(和其他地方)的eval / apply事物将评估者的两个主要部分分开。第一部分,即eval
正在做的事情,正在处理代码的语法翻译到它的含义 - 但除了调度表达式类型之外几乎什么也没做。正如您在本书中所看到的,各种“特殊形式”有各种eval-foo
,因为每种“特殊形式”都有自己独特的评估规则。
现在,评估者需要处理的最重要的形式是功能应用。事实上,这个表单没有关键字是非常重要的(否则,你会看到apply
或任何乱抛垃圾的方案/ lisp代码)。相反,如果表单以不是已知特殊形式的东西开始(并且在实际实现中,而不是已知的宏),则评估者将其视为函数应用程序。此时,要评估函数调用,您需要评估函数本身(第一个表单)及其所有参数,然后您需要将第一个值应用于其余部分。这里一个重要的启蒙时刻是要意识到这个eval
和apply
之间存在重大差异 - 前者本身处理语法,但后者处理值
作为旁注,有几个人将此与Scheme和Lisp实现的内置apply
函数混淆。为什么该函数需要使用该语言与SICP点完全无关(粗略地说,它提供了没有它就无法实现的功能,它是从实现到语言的一种反映形式)。我甚至不认为SICP评估员甚至在解释语言中提供apply
。如果你正在寻找更多的启示,那么这样做(采用SICP元循环评估器,并将apply
添加到解释的语言)将是一个很好的反思练习。
答案 1 :(得分:2)
答案 2 :(得分:1)
Apply评估函数调用。它需要一个函数和一个参数列表:(apply fn args)
。如果你有一种支持函数调用的语言,你可能会在你的解释器中有一个apply函数。 Scheme和Javascript之间的区别在于Scheme不仅将这个函数暴露给解释器,而且还暴露给被解释的程序。