首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >元评价器与分析(元)评价器的区别

元评价器与分析(元)评价器的区别
EN

Stack Overflow用户
提问于 2016-01-28 17:12:55
回答 1查看 175关注 0票数 2

第4.1节计算机程序的结构和解释中引入了两种评价方法,即元评价器和分析元评价器。

完整的元级评估器可以在这里找到:https://mitpress.mit.edu/sicp/code/ch4.scm

有分析功能的完整的评估器可以在这里找到:https://mitpress.mit.edu/sicp/code/ch4-analyzingmceval.scm

现在,两者的不同之处在于,分析器eval有分析表达式的分析方法。

代码语言:javascript
复制
(define (eval exp env)
  ((analyze exp) env))

(define (analyze exp)
  (cond ((self-evaluating? exp) 
         (analyze-self-evaluating exp))
        ((quoted? exp) (analyze-quoted exp))
        (...)

例如,如果分析过程这样做的话:

代码语言:javascript
复制
(define (analyze-self-evaluating exp)
  (lambda (env) exp))

或者这个:

代码语言:javascript
复制
(define (analyze-quoted exp)
  (let ((qval (text-of-quotation exp)))
    (lambda (env) qval)))

而元级评估器eval则这样做:

代码语言:javascript
复制
(define (eval exp env)
  (cond ((self-evaluating? exp) exp)
  (...)

(define (text-of-quotation exp) (cadr exp))

我期望分析评估人员在环境中的某个地方缓存以前分析过的结果,但我没有看到这一点。我看不出分析评估人员到底做了什么。

那么,分析评估器到底是做什么的,为什么它会将评估器的速度提高一些呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-01-28 18:23:30

如果您仔细地查看analyze-something函数,您将看到每个函数(一个analyze-self-evaluatinganalyze-variables部分)执行一些操作,然后返回一个lambda。例如:

代码语言:javascript
复制
(define (analyze-if exp)
  (let ((pproc (analyze (if-predicate exp)))
        (cproc (analyze (if-consequent exp)))
        (aproc (analyze (if-alternative exp))))
    (lambda (env)
      (if (true? (pproc env))
          (cproc env)
          (aproc env)))))

在另一名翻译中,我们有:

代码语言:javascript
复制
(define (eval-if exp env)
  (if (true? (eval (if-predicate exp) env))
      (eval (if-consequent exp) env)
      (eval (if-alternative exp) env)))

这里发生了什么事?在第二种情况下,每次计算相同的表达式(例如,因为我们多次执行递归函数的主体),就会在表达式上调用eval-something版本,并再次计算所有内容,包括analyzing-something对应方在返回函数之前执行的内容!

在第一种情况下,分析函数的第一部分只执行一次,多次执行的是它返回的过程。

如果您特别考虑definition的情况,这一点应该很清楚。比较这两种功能:

代码语言:javascript
复制
(define (analyze-definition exp)
  (let ((var (definition-variable exp))
        (vproc (analyze (definition-value exp))))
    (lambda (env)
      (define-variable! var (vproc env) env)
      'ok)))

代码语言:javascript
复制
(define (eval-definition exp env)
  (define-variable! (definition-variable exp)
                    (eval (definition-value exp) env)
                    env)
  'ok)

在第二个函数中,每当表单(definition-value exp)eval中被调用时,该函数都会计算它的值:

代码语言:javascript
复制
...
((definition? exp) (eval-definition exp env))
...

相反,在第一种情况下,您可以看到函数的(analyze (definition-value exp))部分中有一个对let的调用,然后将其结果存储到var中,这样就不会再计算它了。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35067766

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档