4

在 SICP 第 4 章中,通过将语法分析与执行分离来修改元循环求值器,使eval过程如下所示:

(define (eval exp env)
    ((analyze exp) env))

并且书中说这将节省工作,因为analyze将在表达式上调用一次,而执行过程可能会被调用多次。

我的问题是,这种优化是如何工作的?它适用于递归过程调用,但其他情况呢?评估器一个接一个地评估表达式,eval即使它们具有相同的形式,仍然会在每个表达式上被调用。

4

3 回答 3

4

你需要看到几件事情:(a)analyze函数只遍历每个表达式一次,(b) 没有analyze扫描语法之外的代码,(c) 函数analyze返回的函数不会调用自身,因此运行该函数永远不会导致对于语法的任何进一步扫描,(d) 这完全不同于通常的评估函数,其中调用一个函数两次意味着它的语法被扫描了两次。

顺便说一句,一个更好的名字analyzecompile——它确实将输入语言(sexprs)翻译成目标语言(一个函数,在这里充当机器代码)。

于 2012-02-06T06:59:57.817 回答
1

编译器和解释器的区别在于:

编译器只扫描您的源代码一次并将其更改为执行代码(可能是机器代码)。下次执行程序时,直接执行执行代码,不分析源代码,效率高。

但是,每次执行程序时,解释器都会分析源代码。

这种优化仅在您的程序将被多次执行的情况下才有意义。

正如@Eli Barzilay 所说,“一个更好的名称analyzecompile”,您分析的函数就像执行代码。递归函数就像会被多次执行的程序。

于 2013-09-11T03:36:53.947 回答
0

analyze只需进行一次语法分析,并将转换后的等存储definition在环境中,在lookup-variable-value执行相关过程时可以直接使用。

相比之下,原始的元循环评估器扭曲了语法分析和执行,这使得每次执行也调用了语法分析。

此链接可能有帮助: http ://www.cs.brandeis.edu/~mairson/Courses/cs21b/Handouts/feeley-notes.pdf

于 2014-09-10T08:17:15.257 回答