Transcript slides
Lecture 27:
In Praise of Idleness
CS200: Computer Science
University of Virginia
Computer Science
David Evans
http://www.cs.virginia.edu/~evans
Menu
• Lazy Scheme
• Quantum Computing
27 March 2002
CS 200 Spring 2002
2
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.
27 March 2002
CS 200 Spring 2002
3
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!)
27 March 2002
CS 200 Spring 2002
4
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!
27 March 2002
CS 200 Spring 2002
5
In Praise of Idleness
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, 1932
27 March 2002
CS 200 Spring 2002
6
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.
27 March 2002
CS 200 Spring 2002
7
Evaluation of Arguments
• Applicative Order (“eager evaluation”)
– Evaluate all subexpressions before apply
– The standard Scheme rule
• Normal Order (“lazy evaluation”)
– Evaluate arguments just before the value is
needed
– Algol60, Haskell, Miranda
27 March 2002
CS 200 Spring 2002
8
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))))
27 March 2002
CS 200 Spring 2002
9
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))))
27 March 2002
CS 200 Spring 2002
10
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))))
27 March 2002
CS 200 Spring 2002
11
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)))
27 March 2002
CS 200 Spring 2002
12
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))))
27 March 2002
CS 200 Spring 2002
13
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))))
27 March 2002
CS 200 Spring 2002
14
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!
27 March 2002
CS 200 Spring 2002
15
> (lazeval '((lambda (x) ((lambda (x) (+ x x)) x)) 7) the-global-env)
|(lazeval
((lambda (x) ((lambda (x) (+ x x)) x)) 7)
(((+ primitive-procedure #<primitive:+>)
(* primitive-procedure #<primitive:*>)
(- primitive-procedure #<primitive:->))))
| (lazeval
(lambda (x) ((lambda (x) (+ x x)) x))
(define (lazeval expr env)
(((+ primitive-procedure #<primitive:+>)
(cond
(* primitive-procedure
#<primitive:*>)
(- primitive-procedure((self-evaluating?
#<primitive:->)))) expr) expr)
| (procedure
((variable? expr)
(x)
(lazeval (environment-lookup-name expr env) env))
(((lambda (x) (+ x x)) x))
((lambda?
expr)
(((+ primitive-procedure
#<primitive:+>)
(* primitive-procedure #<primitive:*>)
(make-procedure (lambda-parameters expr)
(- primitive-procedure #<primitive:->))))
(lambda-body expr) env))
| (lazapply
((application? expr)
(procedure
(x)
(lazapply (lazeval (application-operator expr) env)
(((lambda (x) (+ x x)) x))
(application-operands expr)
(((+ primitive-procedure #<primitive:+>)
(* primitive-procedure #<primitive:*>) env))
(else
(error "Unknown expression: " exp))))
(- primitive-procedure
#<primitive:->))))
(7)
(((+ primitive-procedure #<primitive:+>)
(* primitive-procedure #<primitive:*>)
(- primitive-procedure #<primitive:->))))
27 March 2002
CS 200 Spring 2002
16
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 March 2002
CS 200 Spring 2002
17
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))
27 March 2002
CS 200 Spring 2002
18
thunky lazeval
(define (lazeval expr env)
(cond
((application? expr)
(lazapply (lazeval (application-operator expr) env)
(application-operands expr)
env))
…
27 March 2002
CS 200 Spring 2002
19
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))))
27 March 2002
CS 200 Spring 2002
20
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))))
27 March 2002
CS 200 Spring 2002
21
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)))))
27 March 2002
CS 200 Spring 2002
22
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)))))
27 March 2002
CS 200 Spring 2002
23
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?
27 March 2002
CS 200 Spring 2002
24
Quantum Computing
27 March 2002
CS 200 Spring 2002
25
Quantum Mechanics
for Dummies
• Light behaves like both a
wave and a particle at the
same time
• A single photon is in many
states at once
• Observing its state forces it
into one state
Books Search Results: we were unable to find exact matches for your search for scheme for dummies
27 March 2002
CS 200 Spring 2002
26
Schrödinger’s Cat
• Put a live cat in a box with cyanide vial
that opens depending on quantum state
• Cat is both dead and alive at the same
time until you open the box
(qeval ‘(define cat (quist “alive” “dead”)))
(qeval ‘(observe (lambda (q) #t) cat)
“dead”
Its only a thought experiment,
or “alive”
27 March 2002
not necessary to try with real cat!
CS 200 Spring 2002
27
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
27 March 2002
CS 200 Spring 2002
28