1 / 32

CS220 Programming Principles

CS220 Programming Principles. 프로그래밍의 이해 2002 가을학기 Class 16: Variations on Evaluator 한 태숙. Syntactic Analysis. Syntax analysis is interleaved with execution. Source of Inefficiency - Syntax is analyzed many times Ex: (define (factorial n) (if (= n 1) 1

shiloh
Télécharger la présentation

CS220 Programming Principles

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. CS220Programming Principles 프로그래밍의 이해 2002 가을학기 Class 16: Variations on Evaluator 한 태숙

  2. Syntactic Analysis • Syntax analysis is interleaved with execution. • Source of Inefficiency - Syntax is analyzed many times Ex: (define (factorial n) (if (= n 1) 1 (* factorial (- n 1))) (factorial 4) • case analysis in eval, extracting operators........

  3. Redesign the Evaluator • Split eval - takes an exp and an env • analyze - takes only exp, and produce a new proc • execute - takes an env and evaluate • We essentially curry the eval procedure to separate these two notion • the analyze procedures creates an execution object, which is a procedure that can be used to complete an evaluation by applying it to an environment. • (lambda (exp env) ...) • (lambda (env) (lambda (exp) .....)

  4. Analyze ; Evaluation consists of (1) analysis, ; followed by (2) execution in an environment (define (eval exp env) ((analyze exp) env)) ; Analyze returns (lambda (env) .....) (define (analyze exp) (cond ((self-evaluating? exp) (analyze-self-evaluating exp)) ((quoted? exp) (analyze-quoted exp)) ((variable? exp) (analyze-variable exp)) ((assignment? exp) (analyze-assignment exp)) ((definition? exp) (analyze-definition exp)) ((if? exp) (analyze-if exp))

  5. ((lambda? exp) (analyze-lambda exp)) ((begin? exp) (analyze-sequence (begin-actions exp))) ((cond? exp) (analyze (cond->if exp))) ((application? exp) (analyze-application exp)) (else (error "Unknown expression type -- ANALYZE" exp))))

  6. Analysis Procedures (define (anayze-self-evluating exp) (lambda (env) exp)) (define (analyze-quoted exp) (let ((qval (text-of-quotation exp))) (lambda (env) qval))) ; variable lookup - in executiontime (define (analyze-variable exp) (lambda (env) (lookup-variable-value exp env)))

  7. ;actual assignment is done in execution time ;but assignment value is analyzed once (define analyze-assignment exp) (let ((var (assignment-variable exp)) (vproc (analyze (assignment-value exp)))) (lambda (env) (set-variable-value! var (vproc env) env) ’ok))) (define (analyze-definition exp) (let ((var (definition-variable exp)) (vproc (analyze (definition-value exp)))) (lambda (env) (define-variable! var (vproc env) env) ’ok)))

  8. ; if expression (define (analyze-if exp) (let ((ppro (analyze (if-predicate exp))) (cpro (analyze (if-condition exp))) (apro (analyze (if-alternative exp)))) (lambda (env) (if (true? (pproc env)) (cproc env) (aproc env))))) ; alayzing body once, applied many times (define (analyze-lambda exp) (let ((vars (lambda-parameter exp)) (bproc (anlyze-sequence (lambda-body exp)))) (lambda (env) (make-procedure vars bproc env))))

  9. ;anlyze each exp in sequence ; combine generated procedure in seq ; execute the procedures in sequence (define (analyze-sequence exps) (define (sequentially proc1 proc2) (lambda (env) (proc1 env) (proc2 env))) (define (loop first-proc rest-procs) (if (null? rest-procs) first-proc (loop (sequentially first-proc (car rest-procs)) (cdr rest-procs)))) (let ((procs (map analyze exps))) (if (null? procs) (error “Empty sequence--ANALYZE”)) (loop (car procs) (cdr procs))))

  10. ;analyze the operator and operands ; and construct an execution procedure that ; calls the operator execution procedure and ; the operand execution procedures (define (analyze-application exp) (let ((fproc (analyze (operator exp))) (aprocs (map analyze (operands exp)))) (lambda (env) (execute-application (fproc env) (map (lambda (aproc) (apoc env)) aproc)))))

  11. (define (execute-application proc args) (cond ((primitive-procedure? proc) (apply-primitive-procedure proc args)) ((compound-procedure? proc) ((procedure-body proc) (extend-environment (procedure-parameter proc) args (procedure-environment proc)))) (else (error “Unknown procdure type -EXECUTE” proc))))

  12. Drill 1 • Draw the execution object used in ((analyze ’y) t-g-e):

  13. Drill 2 • Draw the execution object used in ((analyze ’(if #t 1 2)) t-g-e):

  14. Lazy Evaluation • means “Do not evaluate the arguments of a procedure until you have to” • Normal Order ( cf. applicative order) Ex: (define (try a b) (if (= a 0) 1 b)) (try 0 (/ 1 0)) (define (unless condition usual-v exception-v) (if condition exception-v usual-v )) (unless (= b 0) (/ a b) (begin (display ”exception”) 0))

  15. Lazy vs Eager : example (define (pick-one sym x y z) (cond ((eq? sym ’x) x) ((eq? sym ’y) y) ((eq? sym ’z) z) (else ’who-cares))) ;;;L-eval input: (pick-one (begin (newline) ’y) (display ’did-x) (display ’did-y) (display ’did-z)) ; TWO NEWLINES did-y ;***displayed symbol ;;;L-eval value: #[undefined-value] ;value from DISPLAY

  16. Exercise 4-25 • What happen if we attempt to evaluate (factorial 5)in an applicative order? Will our definitions work in a normal-order language? (define (factorial n) (unless (= n 1) (* n (factorial (- n 1))) 1)) (define (unless condition usual-v exception-v) (if condition exception-v usual-v ))

  17. Evaluate a LAZY application • To change our language, we will modify the evaluator so that primitive procedures still evaluate all arguments before application, but compound procedures will delay the evaluation of each argument until needed • Delayed arguments will be transformed into objects called thunks. • The process of evaluating the expression in a thunk is called forcing

  18. Modifying the evaluator • Modify eval and apply ; application? of eval ((application? exp) (apply (actual-value (operator exp) env) (operands exp) env)) ; getting the value (define (actual-value exp env) (force-it (eval exp env)))

  19. Modifying apply ;delay the arguments (cf. primitive operator) (define (apply procedure arguments env) (cond ((primitive-procedure? procedure) (apply-primitive-procedure procedure (list-of-arg-values arguments env))) ; changed ((compound-procedure? procedure) (eval-sequence (procedure-body procdure) (extend-environment (procedure-parameters procedure) (list-of-delayed-args arguments env) ;changed (procedure-environment procedure)))) (else (error “Unknown procdure type--APPLY” procedure))))

  20. Only differences are: (define (list-of-arg-values exps env) (if (no-operands? exp) ’() (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))))

  21. If needs predicate evaluated (define (eval-if exp env) (if (true? (actual-value (if-predicate exp) env)) (eval (if-consequence exp) env) (eval (if-alternative exp) env)))

  22. Representing thunks (define (force-it obj) (if (thunk? obj) (actual-value (thunk-exp obj) (thunk-env obj)) obj)) (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 (evaluated-thunk? obj) (tagged-list? obj ‘’evaluated-thunk)) (define (thunk-value evaluated-thunk) (cadr evaluated-thunk))

  23. Call By Need • Once a value has been forced, remember it and don’t force again: MEMOIZATION as for streams. (define (force-it obj) (cond((thunk? obj) (let ((result (actual-value (thunk-exp obj) (thunk-env obj)))) (set-car! obj ’evaluated-thunk) (set-car! (cdr obj) result) ;replace exp (set-cdr! (cdr obj) ’()) ;forget env result)) ((evaluated-thunk? obj) (thunk-value obj)) (else obj)))

  24. Driver ; Driver-Loop needs actual-value (define input-prompt “;;; L-Eval input:”) (define output-prompt “;;; L-Eval Value:”) (define (driver-loop) (prompt-for-input input-prompt) (let ((input (read))) (let ((output (actual-value input the-global-environment))) (announce-output output-prompt) (user-print output))) (driver-loop))

  25. Sample Run (define the-global-environment (set-environment)) (driver-loop) ;;; L-Eval input: (define (try a b) (if (= a 0) 1 b)) ;;; L-Eval value: ok ;;; L-Eval input: (try 0 (/ 1 0)) ;;; L-Eval value 1

  26. Streams as Lazy Lists • In Lazy evaluation, List itself is a stream. It is even lazier than stream. • Implement cons with non-strict primitive (define (cons x y) (lambda (m) (m x y))) (define (car z) (z (lambda (p q) p))) (define (cdr z) (z (lambda (p q) q)))

  27. Examples (define (list-ref items n) (if (= n 0) (car items) (list-ref (cdr items)(- n 1))))) (define ones (cons 1 ones)) (define integer (cons 1 (add-lists ones integers) (define add-lists list1 list2) (cond ((null? list1) list2) ((null? list2) list1) (else (cons (+ (car list1) (car list2)) (add-lists (cdr list1)(cdr list2)))))) ;;; L-Eval input: (list-ref integers 17) ;;; L-Eval value 18

  28. Solving Diff Equation - section 3.5.4 (define (integral integrand initial-value dt) (define int (cons initial-value (add-lists (scale-list integrand dt) int))) int) (define solve f y0 dt) (define y (integral dy y0 dt)) (define dy (map f y)) y) ;;; L-Eval input: (list-ref (solve (lambda (x) x) 1 0.001) 1000) ;;; L-Eval value; 2.716924

  29. Changing to Infix Notation (define (operator app) (if (= 3 (length app)) (cadr app) (car app))) (define (operands app) (if (= 3 length app)) (list (car app) (caddr app)) (cdr app))) EX: (3 + 4) (- 10) cf: (+ 1 2 3 4) (max 1 2 3)

  30. Dynamic Scope (define x 10) (define times-x (lambda (y) (* x y))) (define (mul x y) (times-x y)) (mul 3 4) ==> 12 ; dynamic scoping ==> 40 ; static scoping

  31. Implementing Dynamic Scope ((application? exp) (apply (eval (operator exp) env) (list-of-values (operands exp) env) env)) ;; changed

  32. (define (apply procedure arguments env) ;; changed (cond ((primitive-procedure? procedure) (apply-primitive-procedure procedure arguments)) ((compound-procedure? procedure) (eval-sequence (procedure-body procedure) (extend-environment (procedure-parameters procedure) arguments env))) ;; changed (else (error "Unknown procedure type -- APPLY" procedure))))

More Related