1 / 36

The Metacircular Evaluator

The Metacircular Evaluator. Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full. http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-26.html. High level to Low-level reduction. The Programmer. The Computer. Transformation.

sversace
Download Presentation

The Metacircular Evaluator

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full. http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-26.html

  2. High level to Low-level reduction The Programmer The Computer Transformation Command Processing Unit T Program in High Level Language Program in Low Level Machine Language

  3. A Compiler Inputs C High Level Program Machine Level Program The Compiler turns the high level program instructions to Instructions understood by the machine. CPU Outputs

  4. An Interpreter Inputs I High Level Program CPU Outputs The Interpreter is a machine level program, which interprets and executes the high level program line after line…

  5. The Metacircular Evaluator Inputs ME Scheme Program CPU Outputs The Metacircular Evaluator is an Interpreter for Scheme on a machine whose machine language is Scheme.

  6. The Environment Evaluation Model • To evaluatea combination (a compound expression other than a special form), evaluate the subexpressions and then apply the value of the operator subexpression to the values of the operand subexpressions. • To apply a compound procedure to a set of arguments, evaluate the body of the procedure in a new environment. To construct this environment, extend the environment part of the procedure object by a frame in which the formal parameters of the procedure are bound to the arguments to which the procedure is applied.

  7. The Eval/Apply Cycle

  8. The Meta-Circular Evaluator: Eval (define (eval exp env) (cond ((self-evaluating? exp) exp) ((variable? exp) (lookup-variable-value exp env)) ((quoted? exp) (text-of-quotation exp)) ((assignment? exp) (eval-assignment exp env)) ((definition? exp) (eval-definition exp env)) ((if? exp) (eval-if exp env)) ((lambda? exp) (make-procedure (lambda-parameters exp) (lambda-body exp) env)) ((begin? exp) (eval-sequence (begin-actions exp) env)) ((cond? exp) (eval (cond->if exp) env)) ((application? exp) (apply (eval (operator exp) env) (list-of-values (operands exp) env))) (else (error "Unknown expression type -- EVAL" exp)))) Special forms

  9. The Meta-Circular Evaluator: Apply (define (apply procedure arguments) (cond ((primitive-procedure? procedure) (apply-primitive-procedure procedure arguments)) ((compound-procedure? procedure) (eval-sequence (procedure-body procedure) (extend-environment (procedure-parameters procedure) arguments (procedure-environment procedure)))) (else (error "Unknown procedure type" procedure))))

  10. E1 E2 x: 10 plus: (procedure ...) 3. environment manipulation enclosing- environment E2 frame list ofvariables list of values x plus 10 procedure How the Environment Works • Abstractly – in our environment diagrams: • Concretely – our implementation (as in SICP)

  11. E1 Abstractly x: 10 plus: (procedure ...) E2 x: 4 y: 5 E3 E2 E3 E1 frame list ofvariables list of values 5 x y 4 Extending the Environment • (extend-environment '(x y)(list 4 5) E2) Concretely

  12. Extending the environment (define (extend-environment vars vals base-env) (if (= (length vars) (length vals)) (cons (make-frame vars vals) base-env) (if (< (length vars) (length vals)) (error "Too many arguments supplied" vars vals) (error "Too few arguments supplied" vars vals))))

  13. "Scanning" the environment • Look for a variable in the environment... • Look for a variable in a frame... • loop through the list of vars and list of vals in parallel • detect if the variable is found in the frame • If not found in frame (out of variables in the frame),look in enclosing environment

  14. Scanning the environment (define (lookup-variable-value var env) (define (env-loop env) (define (scan vars vals) (cond ((null? vars) (env-loop (enclosing-environment env))) ((eq? var (car vars)) (car vals)) (else (scan (cdr vars) (cdr vals))))) (if (eq? env the-empty-environment) (error "Unbound variable" var) (let ((frame (first-frame env))) (scan (frame-variables frame) (frame-values frame))))) (env-loop env)) (define (enclosing-environment env) (cdr env)) (define (frame-variables frame) (car frame)) (define (frame-values frame) (cdr frame))

  15. If predicate (define (eval-if exp env) (if (true? (eval (if-predicate exp) env)) (eval (if-consequent exp) env) (eval (if-alternative exp) env))) (define (if-predicate exp) (cadr exp)) (define (if-consequent exp) (caddr exp)) (define (if-alternative exp) (if (not (null? (cdddr exp))) (cadddr exp) 'false)) (define (true? x) (not (eq? x #f))) (define (false? x) (eq? x #f))

  16. Eval-definition (define (define-variable! var val env) (let ((frame (first-frame env))) (define (scan vars vals) (cond ((null? vars) (add-binding-to-frame! var val frame)) ((eq? var (car vars)) (set-car! vals val)) (else (scan (cdr vars) (cdr vals))))) (scan (frame-variables frame) (frame-values frame)))) (define (eval-definition exp env) (let ((name (cadr exp)) (defined-to-be (eval (caddr exp) env))) (define-variable! name defined-to-be env) ‘undefined))

  17. Lambda expression (define (eval-lambda exp env) (make-procedure (lambda-parameters exp) (lambda-body exp) env)) (define (lambda-parameters exp) (cadr exp)) (define (lambda-body exp) (cddr exp)) (define (make-procedure parameters body env) (list 'procedure parameters body env))

  18. GE symbolprocedure This datastructure isa procedure! symbol+ symbolx Implementation of lambda (eval '(define twice (lambda (x) (+ x x))) GE) (eval '(lambda (x) (+ x x)) GE) (eval-lambda '(lambda (x) (+ x x)) GE) (make-procedure '(x) ’((+ x x)) GE) (list ’procedure '(x) ’((+ x x)) GE)

  19. symbolprocedure symbol+ symbolx Naming the procedure (eval '(define twice (lambda (x) (+ x x))) GE) symbol primitive schemeprocedure +

  20. Selctors for procedure type (define (compound-procedure? exp) (tag-check exp ‘procedure)) (define (procedure-parameters compound) (cadr compound)) (define (procedure-body compound) (caddr compound)) (define (procedure-env compound) (cadddr compound))

  21. Eval sequence (define (eval-sequence exps env) (cond ((last-exp? exps) (eval (first-exp exps) env)) (else (eval (first-exp exps) env) (eval-sequence (rest-exps exps) env)))) (define (last-exp? seq) (null? (cdr seq))) (define (first-exp seq) (car seq)) (define (rest-exps seq) (cdr seq))

  22. The Meta-Circular Evaluator: Apply (define (apply procedure arguments) (cond ((primitive-procedure? procedure) (apply-primitive-procedure procedure arguments)) ((compound-procedure? procedure) (eval-sequence (procedure-body procedure) (extend-environment (procedure-parameters procedure) arguments (procedure-environment procedure)))) (else (error "Unknown procedure type" procedure))))

  23. GE A names values E1 x 4 Implementation of apply (1) (eval '(twice4) GE) (apply (eval 'twice GE)(map (lambda (e) (eval e GE)) '(4))) (apply (list 'procedure '(x) ’((+ x x)) GE)'(4)) (eval-seq ’((+ x x)) (extend-environment '(x) '(4) GE)) (eval '(+ x x) E1)

  24. GE A names values E1 x 4 Implementation of apply (2) (eval '(+ x x) E1) (apply (eval + E1)(map (lambda (e) (eval e E1)) '(x x))) (apply '(primitive #[add])(list (eval 'x E1) (eval 'x E1))) (apply '(primitive #[add])'(4 4)) (scheme-apply #[add]'(4 4)) 8

  25. (define (foo x y) (lambda (z) (+ x y z))) bar : (lambda (z) (+ 1 2 z)) (define bar (foo 1 2)) (bar 3) We Implemented Lexical Scoping Free variables in an application of procedure f get their values from the procedure where f was defined (by the appropriate lambda special form). Also called static binding

  26. GE foo: bar: p: x ybody: (l (z) (+ x y z)) x: 1y: 2 E1 z: 3 E2 p: zbody: (+ x y z) (+ x y z) | E2=> 6 Lexical Scoping Environment Diagram (define (foo x y) (lambda (z) (+ x y z))) Will always evaluate (+ x y z) in a new environment inside the surrounding lexical environment. (define bar (foo 1 2)) (bar 3)

  27. Alternative Model: Dynamic Scoping • Dynamic scope: • Look up free variables in the caller's environment rather than the surrounding lexical environment • Example: (define x 11) (define (pooh x) (bear 20)) (define bear (lambda (y) (+ x y))) (pooh 9) => 29

  28. GE pooh: bear: E1 x: 9 p: x body: (bear 20) p: y body: (+ x y) E2 y: 20 Dynamic Scoping Environment Diagram (define x 11) (define (pooh x) (bear 20)) Will evaluate (+ x y) in an environment that extendsthe caller's environment. (define (bear y)(+ x y)) (pooh 9) x:11 (+ x y) | E2=> 29

  29. A "Dynamic" Version of Scheme (define (d-eval exp env) (cond ((self-evaluating? exp) exp) ((variable? exp) (lookup-variable-value exp env)) ... ((lambda? exp) (make-procedure (lambda-parameters exp) (lambda-body exp) '*no-environment*)) ;CHANGE: no env ... ((application? exp) (d-apply (d-eval (operator exp) env) (list-of-values (operands exp) env) env)) ;CHANGE: add env (else (error "Unknown expression -- M-EVAL" exp))))

  30. A "Dynamic" Scheme – d-apply (define (d-apply procedure arguments calling-env) (cond ((primitive-procedure? procedure) (apply-primitive-procedure procedure arguments)) ((compound-procedure? procedure) (eval-sequence (procedure-body procedure) (extend-environment (procedure-parameters procedure) arguments calling-env))) ;CHANGE: use calling env (else (error "Unknown procedure" procedure))))

  31. Lazy evaluation

  32. How can we implement lazy evaluation? (define (l-apply procedure arguments env) ; changed (cond ((primitive-procedure? procedure) (apply-primitive-procedure procedure (list-of-arg-values arguments env))) ((compound-procedure? procedure) (l-eval-sequence (procedure-body procedure) (extend-environment (procedure-parameters procedure) (list-of-delayed-args arguments env) (procedure-environment procedure)))) (else (error "Unknown proc" procedure))))

  33. Actual vs. Delayed Values (define (list-of-arg-values exps env) (if (no-operands? exps) '() (cons (actual-value (first-operand exps) env) (list-of-arg-values (rest-operands exps) env)))) (define (list-of-delayed-args exps env) (if (no-operands? exps) '() (cons (delay-it (first-operand exps) env) (list-of-delayed-args (rest-operands exps) env))))

  34. thunk exp env Representing Thunks • Abstractly – a thunk is a "promise" to return a value when later needed ("forced") • Concretely – our representation: Eval never “works” on a thunk, thunks are only passed as values in the environment!

  35. Thunks – delay-it and force-it (define (delay-it exp env) (list 'thunk exp env)) (define (thunk? obj) (tagged-list? obj 'thunk)) (define (thunk-exp thunk) (cadr thunk)) (define (thunk-env thunk) (caddr thunk)) (define (force-it obj) (cond ((thunk? obj) (actual-value (thunk-exp obj) (thunk-env obj))) (else obj))) (define (actual-value exp env) (force-it (l-eval exp env)))

  36. l-eval (define (l-eval exp env) (cond ((self-evaluating? exp) exp) ... ((application? exp (l-apply (actual-value (operator exp) env) (operands exp) env)) (else (error "Unknown expression" exp))))

More Related