Download presentation
Presentation is loading. Please wait.
1
David Evans http://www.cs.virginia.edu/evans CS200: Computer Science University of Virginia Computer Science Lecture 26: In Praise of Idleness
2
28 March 2003CS 200 Spring 20032 Menu Implementing Environments PS8 Demo Lazy Scheme
3
28 March 2003CS 200 Spring 20033 Environmental Model of Evaluation 1.To evaluate a combination, evaluate all the subexpressions and apply the value of the first subexpression to the values of the other subexpressions. 2.To apply a compound procedure to a set of arguments, evaluate the body of the procedure in a new environment. The parent of the new environment is the procedure’s environment; the frame is a new frame that contains places with the formal parameters bound to the arguments.
4
28 March 2003CS 200 Spring 20034 mapply (define (mapply procedure operands) (cond ((primitive-procedure? procedure) (apply-primitive procedure operands)) ((compound-procedure? procedure) (meval-sequence (procedure-body procedure) (extend-environment (procedure-parameters procedure) operands (procedure-environment procedure)))) (else (error “Can’t apply: " procedure))))
5
28 March 2003CS 200 Spring 20035 Representing Environments An environment is a frame and a parent. x : 4 (define (make-new-environment frame env) (cons frame env)) (define (first-frame env) (car env)) (define (enclosing-environment env) (cdr env))
6
28 March 2003CS 200 Spring 20036 Representing Frames A frame is a list of name-value pairs. x : 4 (define (make-empty-frame) (list)) y : 3
7
28 March 2003CS 200 Spring 20037 extend-environment (define (extend-environment names values env) (make-new-environment (map (lambda (name value) (cons name value)) names values) env))
8
28 March 2003CS 200 Spring 20038 meval (define (meval expr env) (cond ((self-evaluating? expr) expr) ((variable? expr) (environment-lookup-name expr env)) ((lambda? expr) (make-procedure (lambda-parameters expr) (lambda-body expr) env)) ((application? expr) (mapply (meval (application-operator expr) env) (map (lambda (subexpr) (meval subexpr env)) (application-operands expr)))) (else (error "Unknown expression: " exp))))
9
28 March 2003CS 200 Spring 20039 environment-lookup-name (define (environment-lookup-name name env) (if (null? env) (error "No binding " name) (if (frame-contains? name (first-frame env)) (frame-lookup-name name (first-frame env)) (environment-lookup-name name (enclosing-environment env))))) (define (frame-lookup-name name frame) (if (null? frame) (error "Name not found:" name) (if (eq? (car (car frame)) name) (cdr (car frame)) (frame-lookup-name name (cdr frame)))))
10
28 March 2003CS 200 Spring 200310 Metalinguistic Abstraction Now we know how to implement a Scheme evaluator, we can change the language to make it behavior differently PS7: –Add new special forms ( quist, observe ) –Add new kinds of data (quist’s) for which applications are evaluated differently Today: –Change how expressions are evaluated Next week: –Add type checking to catch programming errors
11
28 March 2003CS 200 Spring 200311 Lazy Evaluation Don’t evaluate expressions until their value is really needed. –We might save work this way, since sometime we don’t need the value of an expression –We might change the meaning of some expressions, since the order of evaluation matters Not a wise policy for problem sets (the values will always be needed!)
12
28 March 2003CS 200 Spring 200312 Lazy Examples > (meval ‘((lambda (x) 3) (* 2 2)) the-global-environment) 3 > (lazeval ‘((lambda (x) 3) (* 2 2)) the-global-env) 3 > (meval ‘((lambda (x) 3) (* 2 2)) (car 3)) error – can’t take car of 3 > (lazeval ‘((lambda (x) 3) (car 3)) the-global-env) 3 > (meval ‘((lambda (x) 3) (loop-forever)) the-global-env) no value – loops forever > (lazeval ‘((lambda (x) 3) (loop-forever)) the-global-env) 3 laziness can be useful!
13
28 March 2003CS 200 Spring 200313 Ordinary men and women, having the opportunity of a happy life, will become more kindly and less persecuting and less inclined to view others with suspicion. The taste for war will die out, partly for this reason, and partly because it will involve long and severe work for all. Good nature is, of all moral qualities, the one that the world needs most, and good nature is the result of ease and security, not of a life of arduous struggle. Modern methods of production have given us the possibility of ease and security for all; we have chosen, instead, to have overwork for some and starvation for others. Hitherto we have continued to be as energetic as we were before there were machines; in this we have been foolish, but there is no reason to go on being foolish forever. Bertrand Russell, In Praise of Idleness, 1932 (co-author of Principia Mathematica, proved wrong by Gödel’s proof)
14
PS8 Demo: R U Like Me? Rachel Dada, Grace Deng, Jacques Fourier, Shawn O’Hargan http://www.people.virginia.edu/~brs9e/cs200/home.php3
15
28 March 2003CS 200 Spring 200315 PS8 Projects Team requests must be received by 5pm Monday –I will only grant team requests that include a description of your project idea Remember that you’re projects should be 1 Million times better than last year’s!
16
28 March 2003CS 200 Spring 200316 1.To evaluate a combination, evaluate all the subexpressions and apply the value of the first subexpression to the values of the other subexpressions. 2.To apply a compound procedure to a set of arguments, evaluate the body of the procedure in a new environment. The parent of the new environment is the procedure’s environment; the frame is a new frame that contains places with the formal parameters bound to the argument expressions. When a formal parameter is first used, evaluate the argument expression to get its value. How do we make our evaluation rules lazier?
17
28 March 2003CS 200 Spring 200317 Evaluation of Arguments Applicative Order (“eager evaluation”) –Evaluate all subexpressions before apply –The standard Scheme rule, Java Normal Order (“lazy evaluation”) –Evaluate arguments just before the value is needed –Algol60 (sort of), Haskell, Miranda “Normal” Scheme order is not “Normal Order”!
18
28 March 2003CS 200 Spring 200318 meval (define (meval expr env) (cond ((self-evaluating? expr) expr) ((variable? expr) (environment-lookup-name expr env)) ((lambda? expr) (make-procedure (lambda-parameters expr) (lambda-body expr) env)) ((application? expr) (mapply (meval (application-operator expr) env) (map (lambda (subexpr) (meval subexpr env)) (application-operands expr)))) (else (error "Unknown expression: " exp))))
19
28 March 2003CS 200 Spring 200319 lazeval (define (lazeval expr env) (cond ((self-evaluating? expr) expr) ((variable? expr) (environment-lookup-name expr env)) ((lambda? expr) (make-procedure (lambda-parameters expr) (lambda-body expr) env)) ((application? expr) (lazapply (lazeval (application-operator expr) env) (application-operands expr) env)) (else (error "Unknown expression: " exp))))
20
28 March 2003CS 200 Spring 200320 lazapply (define (lazapply procedure operands env) (cond ((primitive-procedure? procedure) (apply-primitive procedure operands)) ((compound-procedure? procedure) (lazeval-sequence (procedure-body procedure) (extend-environment (procedure-parameters procedure) operands (procedure-environment procedure)))) (else (error "Unknown applicator: " procedure))))
21
28 March 2003CS 200 Spring 200321 apply-primitive (define (apply-primitive procedure operands) ;;; The underlying Scheme apply (apply (primitive-procedure-procedure procedure) operands)) (define (lazapply-primitive procedure operands env) ;;; The underlying Scheme apply (apply (primitive-procedure-procedure procedure) (map (lambda (op) (lazeval op env)) operands)))
22
28 March 2003CS 200 Spring 200322 lazeval (define (lazeval expr env) (cond ((self-evaluating? expr) expr) ((variable? expr) (environment-lookup-name expr env)) ((lambda? expr) (make-procedure (lambda-parameters expr) (lambda-body expr) env)) ((application? expr) (lazapply (lazeval (application-operator expr) env) (application-operands expr) env)) (else (error "Unknown expression: " exp))))
23
28 March 2003CS 200 Spring 200323 lazeval (define (lazeval expr env) (cond ((self-evaluating? expr) expr) ((variable? expr) (lazeval (environment-lookup-name expr env) env)) ((lambda? expr) (make-procedure (lambda-parameters expr) (lambda-body expr) env)) ((application? expr) (lazapply (lazeval (application-operator expr) env) (application-operands expr) env)) (else (error "Unknown expression: " exp))))
24
28 March 2003CS 200 Spring 200324 Are we lazy? > (lazeval '((lambda (x) (* x x)) 3) the-global-env) 9 > (lazeval '(define loop-forever (lambda () (loop-forever))) the-global-env) ok > (lazeval '((lambda (x) 12) (loop-forever)) the-global-env) 12 > (meval '((lambda (x) ((lambda (x) (+ x x)) x)) 7) the-global-env) 14 > (lazeval '((lambda (x) ((lambda (x) (+ x x)) x)) 7) the-global-env) Doesn’t halt!
25
28 March 2003CS 200 Spring 200325 > (lazeval '((lambda (x) ((lambda (x) (+ x x)) x)) 7) the-global-env) |(lazeval ((lambda (x) ((lambda (x) (+ x x)) x)) 7) (((+ primitive-procedure # ) (* primitive-procedure # ) (- primitive-procedure # )))) | (lazeval (lambda (x) ((lambda (x) (+ x x)) x)) (((+ primitive-procedure # ) (* primitive-procedure # ) (- primitive-procedure # )))) | (procedure (x) (((lambda (x) (+ x x)) x)) (((+ primitive-procedure # ) (* primitive-procedure # ) (- primitive-procedure # )))) | (lazapply (procedure (x) (((lambda (x) (+ x x)) x)) (((+ primitive-procedure # ) (* primitive-procedure # ) (- primitive-procedure # )))) (7) (((+ primitive-procedure # ) (* primitive-procedure # ) (- primitive-procedure # )))) (define (lazeval expr env) (cond ((self-evaluating? expr) expr) ((variable? expr) (lazeval (environment-lookup-name expr env) env)) ((lambda? expr) (make-procedure (lambda-parameters expr) (lambda-body expr) env)) ((application? expr) (lazapply (lazeval (application-operator expr) env) (application-operands expr) env)) (else (error "Unknown expression: " exp))))
26
28 March 2003CS 200 Spring 200326 Fixing Lazeval We need to only evaluate things once – the first time we need the value of a name We need to evaluate them in the correct environment Instead of putting the expression in the frame, make a new kind of object called a thunk that packages the expression with the evaluation environment. The first time we need the value associated with a name, evaluate the thunk and put the value in the name’s place.
27
28 March 2003CS 200 Spring 200327 I thunk I can… (define (make-thunk expr env) (list 'thunk expr env)) (define (thunk? expr) (tagged-list? expr 'thunk)) (define (thunk-expr thunk) (cadr thunk)) (define (thunk-env thunk) (caddr thunk))
28
28 March 2003CS 200 Spring 200328 thunky lazeval (define (lazeval expr env) (cond ((application? expr) (lazapply (lazeval (application-operator expr) env) (application-operands expr) env)) …
29
28 March 2003CS 200 Spring 200329 thunky lazapply (define (lazapply procedure operands env) (cond ((primitive-procedure? procedure) (lazapply-primitive procedure (map (lambda (op) (lazeval op env)) operands))) ((compound-procedure? procedure) (lazeval-sequence (procedure-body procedure) (extend-environment (procedure-parameters procedure) (map (lambda (op) (make-thunk op env)) operands) (procedure-environment procedure)))) (else (error "Unknown applicator: " procedure))))
30
28 March 2003CS 200 Spring 200330 thunky names (define (lazeval expr env) (cond ((self-evaluating? expr) expr) ((variable? expr) (environment-get-value! expr env)) ((lambda? expr) (make-procedure (lambda-parameters expr) (lambda-body expr) env)) ((definition? expr) (define-variable! (definition-variable expr) (lazeval (definition-value expr) env) env)) ((application? expr) (lazapply (lazeval (application-operator expr) env) (application-operands expr) env)) (else (error "Unknown expression: " exp))))
31
28 March 2003CS 200 Spring 200331 environment-lookup-name (define (environment-lookup-name name env) (if (null? env) (error "No binding " name) (if (frame-contains? name (first-frame env)) (frame-lookup-name name (first-frame env)) (environment-lookup-name name (enclosing-environment env)))))
32
28 March 2003CS 200 Spring 200332 environment-get-value! (define (environment-get-value! name env) (if (null? env) (error "No binding for" name) (if (frame-contains? name (first-frame env)) (let ((np (frame-lookup-name name (first-frame env)))) (if (thunk? (cdr np)) (set-cdr! np (lazeval (thunk-expr (cdr np)) (thunk-env (cdr np))))) (cdr np)) (environment-get-value! name (enclosing-environment env)))))
33
28 March 2003CS 200 Spring 200333 Laziness is Good? > (lazeval '(define true (lambda (x y) x)) the-global-env) ok > (lazeval '(define false (lambda (x y) y)) the-global-env) ok > (lazeval '(define if (lambda (pred tbranch fbranch) (pred tbranch fbranch))) the-global-env) ok > (lazeval '(if true 3 (loop-forever)) the-global-env) 3 Problem Set 7, Question 2: why does this work in LazyScheme, but not in MiniScheme?
34
28 March 2003CS 200 Spring 200334 Charge Don’t let Lazy Scheme happen to you! –PS7 is long and hard – don’t wait to start it! Next week –Another Scheme Variation: type checking –Problem classification practice (when the weather is good) P, NP, Decidable; NP-Complete, Undecidable –Networking
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.