Lecture 5A: Assignment, State, and Side-Effects
https://youtu.be/dO1aqPBJCPg
text § 3.1 & 3.2
"so far we've invented enough programming to do some very complicated
things."
so far we have worked without assignment, "in pascal a very basic
thing."
so now we are going to do a "horrible" thing: introduce assignment
the reason is to give the power of another means of decomposition
so far we have been writing funtional programs
these programs can be understood by substitution
time axis | <before> | | (set! <var> <val>) -------+------------ | <after> | <var> has value | <val> | v
(define count 1) (define (demo x) (set! count (1+ count)) (+ x count)) => (demo 3) 5 => (demo 3) 6
demo is not a function. it leads to multiple values, based on TIME
substitution is static – it describes things that are true, not
things that change
"this is a very bad thing!! going to cause a lot of trouble!!"
but there's a good reason
FUNCTIONAL VERSION (substitution works):
(define (fact n) (define (iter m i) (cond ((> i n) m) (else (iter (* i m) (+ i 1))))) (iter 1 1))
IMPERATIVE VERSION (substitution eats shit):
(define (fact-i n) (let ((i 1) (m 1)) (define (loop) (cond ((> i n) m) (else (set! m (* i m)) ;; a subtle bug (set! i (+ i 1)) ;; can live here (loop)))) (loop)))
–> break
we have to transition to the environment model
there is a bunch of important and unfortunate terminology
- bound variables
- var v is bound in an exp e if the meaning of e
is unchanged by the uniform replacement of var w (not in e) for
every occurance of v in e
λ is the essential variable binder
(λ (y) ((λ (x) (* x y)) 3))
there are two bound vars: x and y
if replaced all the y's with w's, it's the same procedure
(λ (x) (* x y))
y is not bound.
- free variable
- var v is free in an exp e if the meaning of e is
changed by the uniform replacement of a var w
(not in e) for every occurance of v in e - scope
- the lambda bind the vars in it's arg list to a scope
environments are ways of doing substitution virtually
envs are made out of frames, chained together, by parent links
procedures are made out of two parts
- some code
- an environment
a var in the procedure is either bound or free.
RULE 1: a procedure is applied to its args by building a frame,
binding formal params to the actual args of the call, then
evaluating the body of the procedure in the context of the new
env. the new frame has as its enclosing env the env part of the
procedure obj being applied
RULE 2: a λ exp is evaluated relative to an env by forming a new
procedure obj, combining the text (code) of the λ exp with a pointer
to the env of evaluation
–> break
now,,, WHY would gjs have done this cruel thing to us?
(define make-counter (lambda (n) (lambda () (set! n (1+ n)) n)))
we have to make an env for this procedure
| + * / - GLOBAL | cons car | make-counter | C1 C2 +---------------------------------------------- ^ ^ ^ ^ env | | env | | | | | | proc (00)---+ -- |n=0| proc (00)---+ -- |n=10| | | (λ ...) (λ ...)
(define C1 (make-counter 0)) (define C2 (make-counter 10))
ACTION AND IDENTITY
we say that an action a had an effect on an obj x if some property p
which was true of x before a became false of x after a
we say that two objs, x and y, are the same if any action which has
an effect on x has the same effect on y
A FUN GAME:
;;; cesaro's method for estimating π: ;;; Prob(gcd(n1,n2)=1) = 6/(pi*pi) (define (estimate-pi n) (sqrt (/ 6 (monte-carlo n cesaro)))) (define (cesaro) (= (gcd (rand) (rand)) 1))
;;; the monte-carlo technique (define (monte-carlo trials experiment) (define (iter remaining passed) (cond ((= remaining 0) (/ passed trials)) ((experiment) (iter (-1+ remaining) (1+ passed))) (else (iter (-1+ remaining) passed)))) (iter trials 0))
;;; the random number generator ;;; containing hidden local state (define rand (let ((x random-init)) (lamda () (set! x (rand-update x)) x)))
gjs name-checks donald knuth!
"things are seldom what they seem, skim milk masquerades as cream…"
- gilbert & sullivan (hms pinafore)