In section 4.1 of the Structure and Interpretation of Computer Programs there are two evaluators introduced, being the metacircular evaluator and the analysing metacircular evaluator.
The full metacircular evaluator can be found here: https://mitpress.mit.edu/sicp/code/ch4.scm
And the full metacircular evaluator with analysis can be found here: https://mitpress.mit.edu/sicp/code/ch4-analyzingmceval.scm
Now, the difference between the two is that the analysing evaluator eval
has analysis methods for analysing the expression.
(define (eval exp env)
((analyze exp) env))
(define (analyze exp)
(cond ((self-evaluating? exp)
(analyze-self-evaluating exp))
((quoted? exp) (analyze-quoted exp))
(...)
Where the analysis procedure does for example this:
(define (analyze-self-evaluating exp)
(lambda (env) exp))
or this:
(define (analyze-quoted exp)
(let ((qval (text-of-quotation exp)))
(lambda (env) qval)))
Whereas the metacircular evaluator eval
does this:
(define (eval exp env)
(cond ((self-evaluating? exp) exp)
(...)
(define (text-of-quotation exp) (cadr exp))
What I expected the analysing evaluator to do is caching previously analyzed results somewhere in the environment, but I do not see this. I don't see what the analysing evaluator exactly does.
So, what does the analyzing evaluator exactly do and why does it speed up the evaluator by a fair bit?