Download presentation
Presentation is loading. Please wait.
Published byKristopher Morrison Modified over 9 years ago
1
Example 1: counter (set! vs set-box!) 1 Imperative Programming: Mutable data and local state (define counter (let ((count 0)) (lambda () (set! count (+ count 1)) count))) (define counter (let ((count 0)) (lambda () (set! count (+ count 1)) count))) > (counter) 1 > (define count 5) > (counter) 2 o count is the local state of the counter object. o In functional languages, objects are implemented as runtime generated closures. GE counter (lambda () (set!... E1 count :0 P = B = (set! count... P = count B = (lambda () (set!... (set! count... E2 1
2
Example 1: counter (set! vs set-box!) 2 Imperative Programming: Mutable data and local state (define counter (let ((count 0)) (lambda (modifer) (modifer count) count))) (define counter (let ((count 0)) (lambda (modifer) (modifer count) count))) > (counter (lambda(x) (set! x (+ x 1)))) 1 > (counter (lambda(x) (set! x (+ x 1)))) 1 (modifier count)… E2 modifier P = x B = (set! x... x : 0 E3 (set! x... GE counter (lambda (modifier)... E1 count :0 P = modifier B = (modifier count)… P = count B = (lambda (modifier)... 1
3
Example 1: counter (set! vs set-box!) 3 Imperative Programming: Mutable data and local state (define counter (let ((count (box 0))) (lambda (modifer) (modifer count) (unbox count)))) (define counter (let ((count (box 0))) (lambda (modifer) (modifer count) (unbox count)))) > (counter (lambda(x) (set! x (+ x 1)))) 1 > (counter (lambda(x) (set! x (+ x 1)))) 2 (modifier count)… E2 modifier P = x B = (set! x... x:x: E3 (set! x... GE counter (lambda (modifier)... E1 count : P = modifier B = (modifier count)… P = count B = (lambda (modifier)... 0 1
4
Example 2: Boxes in Lists 4 (define my-box (box 5)) (define my-list-1 (list 1 my-box 2)) (define my-list-2 (list my-box 4 5)) (define my-box (box 5)) (define my-list-1 (list 1 my-box 2)) (define my-list-2 (list my-box 4 5)) my-list-1 12 my-list-2 4 5 Imperative Programming: Mutable data and local state > my-list-1 '(1 #&5 2) > my-list-2 '(#&5 4 5) What elements of the list can we modify? > (set! (car my-list-1) 3) Error >(set-box! (car my-list-2) 'hello) >(set! my-box 'cat) > my-list-1 '(1 #&hello 2) 5 5 hello my-box
5
Example 3: Circular Lists o A pseudo-circular lists can be generated as a list where each of its members is a boxed-value. o The value of the last box can be set to the list itself. 5 circ-list > (define circ-list (list (box 1) (box 2) (box 3))) 12 3 circ-list > (set-box! (caddr circ-list) circ-list) 12 o It is only a pseudo-circular because the last member of the list still points to '(). Imperative Programming: Mutable data and local state
6
Example 4: letrec o The letrec expression can be used to define local recursive procedures. o Not supported by the functional programming model (applicative-eval) without rewriting the code. o Can be supported by the imperative programming model (based on the environment model). 6 (letrec ((f1 lambda-exp1)... (fn lambda-expn)) e1...em) (let ((f1 ’unassigned)... (fn ’unassigned)) (set-box! f1 lambda-exp1)... (set-box! fn lambda-expn) e1...em)) To support the evaluation of a letrec expression, it is handled as a derived expression: Imperative Programming: Mutable data and local state
7
Example 4 (cont’d): The following is an example of a derived letrec expression: 7 (letrec ((fact (lambda (n) (if (= n 0) 1 (* n (fact (- n 1))))))) (fact 3)) (letrec ((fact (lambda (n) (if (= n 0) 1 (* n (fact (- n 1))))))) (fact 3)) (let ((fact 'unassigned)) (set! fact (lambda (n) (if (= n 0) 1 (* n (fact (- n 1)))))) (fact 3)) (let ((fact 'unassigned)) (set! fact (lambda (n) (if (= n 0) 1 (* n (fact (- n 1)))))) (fact 3)) ( (lambda (fact) (set! fact (lambda (n) (if (= n 0) 1 (* n (fact (- n 1)))))) (fact 3) ) 'unassigned ) ( (lambda (fact) (set! fact (lambda (n) (if (= n 0) 1 (* n (fact (- n 1)))))) (fact 3) ) 'unassigned ) Imperative Programming: Mutable data and local state
8
Example 4 (cont’d): Evaluate the following code 8 1.((lambda (fact) 2. (set! fact (lambda (n) 3. (if (= n 0) 4. 1 5. (* n (fact (- n 1)))))) 6. (fact 3)) 8. 'unassigned) 1.((lambda (fact) 2. (set! fact (lambda (n) 3. (if (= n 0) 4. 1 5. (* n (fact (- n 1)))))) 6. (fact 3)) 8. 'unassigned) GE P: fact B: (set!... (fact 3)) fact: 'unassigned E1 (set!.. (fact 3)) n:3 E2 (if…) Imperative Programming: Mutable data and local state n:2 E3 (if... n:1 E4 (if... n:0 E5 (if... P: n B: (if… )
9
GE P: fact B: (set!... (fact 3)) fact: 'unassigned E1 (set!.. (fact 3)) n:3 E2 (if…) n:2 E3 (if... n:1 E4 (if... n:0 E5 (if... P: n B: (if… ) GE P: fact B: (set!... (fact 3)) fact: 'unassigned E1 (set!.. (fact 3)) P: n B: (if… )
10
10 Example 5: The chess player o A chess player object is represent by a dispatch procedure. o Based on a given message it invokes internal procedures of the object. o total and steps are the object’s local state variables. (define make-player (lambda (total) (letrec ((steps 0) (get-steps (lambda () steps)) (set-steps! (lambda () (set! steps (+ steps 1)))) (get-total (lambda () total)) (set-total! (lambda (piece) (let ((piece-value (cond ((eq? piece 'queen) 9) ((eq? piece 'rook) 5) … (else 0)))) (set! total (- total piece-value))))) (dispatch (lambda (m) (cond ((eq? m 'set-total) set-total!) ((eq? m 'set-steps) set-steps!) ((eq? m 'get-total) get-total) ((eq? m 'get-steps) get-steps) ( else (error "Unknown request")))))) dispatch))) (define make-player (lambda (total) (letrec ((steps 0) (get-steps (lambda () steps)) (set-steps! (lambda () (set! steps (+ steps 1)))) (get-total (lambda () total)) (set-total! (lambda (piece) (let ((piece-value (cond ((eq? piece 'queen) 9) ((eq? piece 'rook) 5) … (else 0)))) (set! total (- total piece-value))))) (dispatch (lambda (m) (cond ((eq? m 'set-total) set-total!) ((eq? m 'set-steps) set-steps!) ((eq? m 'get-total) get-total) ((eq? m 'get-steps) get-steps) ( else (error "Unknown request")))))) dispatch))) Imperative Programming: Mutable data and local state
11
11 (define make-player (lambda (total) ( (lambda (steps get-steps set-steps! get-total set-total! dispatch) (set-box! steps (box 0)) (set-box! get-steps (lambda () (unbox steps))) (set-box! set-steps! (lambda () (set-box! steps (+ (unbox steps) 1)))) (set-box! get-total (lambda () (unbox total))) (set-box! set-total! (lambda (piece) (let ((piece-value (cond ((eq? piece 'queen) 9) ((eq? piece 'rook) 5) ((eq? piece 'bishop) 3) ((eq? piece 'knight) 3) ((eq? piece 'pawn) 1) ( else 0)))) (set-box! total (- (unbox total) piece-value))))) (set-box! dispatch (lambda (m) (cond ((eq? m 'set-total) set-total!) ((eq? m 'set-steps) set-steps!) ((eq? m 'get-total) get-total) ((eq? m 'get-steps) get-steps) ( else (error "Unknown request"))))) ((lambda (steps get-steps set-steps! get-total set-total! dispatch) dispatch) (unbox steps) (unbox get-steps) (unbox set-steps!) (unbox get-total) (unbox set-total!) (unbox dispatch))) (box 'unassigned) (box 'unassigned) ) ))
12
12 P= total B= ( (lambda (steps… make-player player GE E1 total:39 ( (lambda (steps… P= steps, get-steps …dispatch B= (set! steps…... dispatch)) Example 5 (cont’d): Evaluate - (define player (make-player 39)) E2 Steps : ‘unassigned get-steps: ‘unassigned … dispatch: ‘unassigned 0 P= B= steps P=m B=(cond… Imperative Programming: Mutable data and local state (define make-player (lambda (total) (letrec ((steps 0) (get-steps (lambda () steps))... (set-total! (lambda (piece) (let ((piece-value (cond ((eq? piece 'queen) 9) ((eq? piece 'rook) 5)... (else 0)))) (set! total (- total piece-value))))) (dispatch (lambda (m) (cond ((eq? m 'set-total) set-total!)... ( else (error "Unknown request")))))) dispatch))) (define make-player (lambda (total) (letrec ((steps 0) (get-steps (lambda () steps))... (set-total! (lambda (piece) (let ((piece-value (cond ((eq? piece 'queen) 9) ((eq? piece 'rook) 5)... (else 0)))) (set! total (- total piece-value))))) (dispatch (lambda (m) (cond ((eq? m 'set-total) set-total!)... ( else (error "Unknown request")))))) dispatch)))
13
13 P= total B= ( (lambda (steps… make-player player GE E1 total:39 ( (lambda (steps… P= steps, get-steps …dispatch B= (set! steps…... dispatch)) Example 5 (cont’d): Evaluate - ((player 'set-total) 'queen)) E2 Steps : ‘unassigned get-steps: ‘unassigned … dispatch: ‘unassigned 0 P= B= steps P=m B=(cond… Imperative Programming: Mutable data and local state (define make-player (lambda (total) (letrec ((steps 0) (get-steps (lambda () steps))... (set-total! (lambda (piece) (let ((piece-value (cond ((eq? piece 'queen) 9) ((eq? piece 'rook) 5)... (else 0)))) (set! total (- total piece-value))))) (dispatch (lambda (m) (cond ((eq? m 'set-total) set-total!)... ( else (error "Unknown request")))))) dispatch))) (define make-player (lambda (total) (letrec ((steps 0) (get-steps (lambda () steps))... (set-total! (lambda (piece) (let ((piece-value (cond ((eq? piece 'queen) 9) ((eq? piece 'rook) 5)... (else 0)))) (set! total (- total piece-value))))) (dispatch (lambda (m) (cond ((eq? m 'set-total) set-total!)... ( else (error "Unknown request")))))) dispatch))) E3 m = ‘set-total (cond… E4 piece : ‘queen (let… P= piece-value B= (set! total… 30 Piece-value:9 (set! total… E5
14
14 P= total B= ( (lambda (steps… make-player player GE E1 total:39 ( (lambda (steps… P= steps, get-steps …dispatch B= (set! steps…... dispatch)) E2 Steps : ‘unassigned get-steps: ‘unassigned … dispatch: ‘unassigned 0 P= B= steps P=m B=(cond… P= total B= ( (lambda (steps… make-player player GE E1 total:39 ( (lambda (steps… P= steps, get-steps …dispatch B= (set! steps…... dispatch)) E2 Steps : ‘unassigned get-steps: ‘unassigned … dispatch: ‘unassigned 0 P= B= steps P=m B=(cond… E3 m = ‘set-total (cond… E4 piece : ‘queen (let… P= piece-value B= (set! total… 30 Piece-value:9 (set! total… E5
15
15 Q: Can a while expression be supported in a functional programming evaluator? A: NO! in functional programming there is no change of state. Particularly, the result of evaluating the clause of a while loop will always remain the same. An ability to change state is required! > (env-eval '(define x 0) t-g-e) > (env-eval '(define n 4) t-g-e) > (env-eval '(while (> n 0) (begin (set! x (+ x n)) (set! n (- n 1)))) t-g-e) > (env-eval x t-g-e) 10 Imperative Programming: Adding while Example 6: In the imperative programming evaluator, support for box, unbox, set-box! expressions is added, which motivates supporting while expressions: Syntax: (while ).
16
while? (exp) ; returns true iff exp is a while exp. while-pred (exp) ; returns the predicate of a while exp. while-body (exp) ; returns the body of a while exp. make-while (exp) ; creates a while exp. while? (exp) ; returns true iff exp is a while exp. while-pred (exp) ; returns the predicate of a while exp. while-body (exp) ; returns the body of a while exp. make-while (exp) ; creates a while exp. First, add the relevant parser procedures: 16 Example 6 (cont’d): Imperative Programming: Adding while
17
(define derived? (lambda (exp) (or... (while? exp)))) (define shallow-derive (lambda (exp) (cond... ((while? exp) (while->iteration-expression exp))))) (define shallow-derive (lambda (exp) (cond... ((while? exp) (while->iteration-expression exp))))) 1. Add to derived? 2. Add to shallow-derive 17 Imperative Programming: Adding while – As a derived expression Example 6 (cont’d):
18
(letrec ((iter (lambda () (if (> n 0) (begin (begin (set! x (+ x n)) (set! n (- n 1))) (iter)) 'ok)))) (iter)) (letrec ((iter (lambda () (if (> n 0) (begin (begin (set! x (+ x n)) (set! n (- n 1))) (iter)) 'ok)))) (iter)) 18 Imperative Programming: Adding while – As a derived expression Example 6 (cont’d): Writing the translation procedure, first try: 3. Add the translation procedure: while->iteration-expression… Q: Any problem with the suggested translation? (while (> n 0) (begin (set! x (+ x n)) (set! n (- n 1)))) (while (> n 0) (begin (set! x (+ x n)) (set! n (- n 1))))
19
(letrec ((iter (lambda () (if (> (iter n) 0) (begin (set! n (- n (iter n))) (iter)) 'ok)))) (iter)) (letrec ((iter (lambda () (if (> (iter n) 0) (begin (set! n (- n (iter n))) (iter)) 'ok)))) (iter)) 19 Imperative Programming: Adding while – As a derived expression Example 6 (cont’d): Writing the translation procedure, first try: 3. Add the translation procedure: while->iteration-expression… Q: Any problem with the suggested translation? There might be if iter is a predefined procedure! (define iter (lambda (x) x)) (while (> (iter n) 0) (set! n (- n (iter n)))) (define iter (lambda (x) x)) (while (> (iter n) 0) (set! n (- n (iter n))))
20
(let ((pred (lambda () (> (iter n) 0))) (body (lambda () (set! n (- n (iter n)))))) (letrec ((iter (lambda () (if (pred) (begin (body) (iter)) 'ok)))) (iter))) (let ((pred (lambda () (> (iter n) 0))) (body (lambda () (set! n (- n (iter n)))))) (letrec ((iter (lambda () (if (pred) (begin (body) (iter)) 'ok)))) (iter))) 20 Imperative Programming: Adding while – As a derived expression Example 6 (cont’d): Writing the translation procedure, second try: 3. Add the translation procedure: while->iteration-expression… (while (> n 0) (begin (set! x (+ x n)) (set! n (- n 1)))) (while (> n 0) (begin (set! x (+ x n)) (set! n (- n 1))))
21
(define while->iteration-expression (lambda (exp) (let ((pred (make-lambda ‘() (list (while-pred exp)))) (body (make-lambda ‘() (list (while-body exp))))) (make-let (list (list ‘pred pred) (list ‘body body)) (list (make-letrec (list (list 'iter (make-lambda (list) (list (make-if (make-application ‘pred (list)) (make-begin (list (make-application ‘body (list)) (make-application 'iter (list)))) '(quote ok)))))) (list (make-application 'iter (list))))))))) (define while->iteration-expression (lambda (exp) (let ((pred (make-lambda ‘() (list (while-pred exp)))) (body (make-lambda ‘() (list (while-body exp))))) (make-let (list (list ‘pred pred) (list ‘body body)) (list (make-letrec (list (list 'iter (make-lambda (list) (list (make-if (make-application ‘pred (list)) (make-begin (list (make-application ‘body (list)) (make-application 'iter (list)))) '(quote ok)))))) (list (make-application 'iter (list))))))))) 21 Example 6 (cont’d): The translation procedure Imperative Programming: Adding while – As a derived expression
22
(define special-form? (lambda (exp) (or (quoted? exp)... (while? exp)))) (define special-form? (lambda (exp) (or (quoted? exp)... (while? exp)))) (define eval-special-form (lambda (exp env) (cond... ((while? exp) (eval-while exp env))))) (define eval-special-form (lambda (exp env) (cond... ((while? exp) (eval-while exp env))))) (define eval-while (lambda (exp env) (let ((pred (while-pred exp)) (body (while-body exp))) (if (env-eval pred env) (begin (env-eval body env) (eval-while exp env)) 'ok)))) (define eval-while (lambda (exp env) (let ((pred (while-pred exp)) (body (while-body exp))) (if (env-eval pred env) (begin (env-eval body env) (eval-while exp env)) 'ok)))) 22 Imperative Programming: Adding while – As a special form 1. Add to special-form?. Example 6 (cont’d): 2. Add an eval-special-form procedure 3. Add an eval-while procedure
23
23 Imperative Programming: Adding while – As a special form Example 6 (cont’d): Adding while to the compiler as a special form (define analyze-special-form (lambda (exp) (cond... ((while? exp) (analyze-while exp))))) (define analyze-special-form (lambda (exp) (cond... ((while? exp) (analyze-while exp))))) 1. Add to special-form?. 2. Make analysis of the expression components. Rules of thumb are: a. Recursively analyze the exp components. b. Curry to produce a ready-to-execute procedure. The use (a) and (b) to translate evaluator code to analyzer code requires the evaluator code to be written properly. The translated code should not include calls to eval or produce new code. (define eval-while (lambda (exp env) (let ((pred (while-pred exp)) (body (while-body exp))) (if (env-eval pred env) (begin (env-eval body env) (eval-while exp env)) 'ok)))) (define eval-while (lambda (exp env) (let ((pred (while-pred exp)) (body (while-body exp))) (if (env-eval pred env) (begin (env-eval body env) (eval-while exp env)) 'ok)))) (define analyze-while (lambda (exp) (let ((pred (analyze (while-pred exp))) (body (analyze (while-body exp)))) (lambda (env) (if (pred env) (begin (body env) ((analyze-while exp) env)) 'ok))))) (define analyze-while (lambda (exp) (let ((pred (analyze (while-pred exp))) (body (analyze (while-body exp)))) (lambda (env) (if (pred env) (begin (body env) ((analyze-while exp) env)) 'ok))))) a b BIG NO-NO!
24
24 Imperative Programming: Adding while – As a special form Example 6 (cont’d): Adding while to the compiler as a special form (define analyze-special-form (lambda (exp) (cond... ((while? exp) (analyze-while exp))))) (define analyze-special-form (lambda (exp) (cond... ((while? exp) (analyze-while exp))))) 1. Add to special-form?. 2. Make analysis of the expression components. Rules of thumb are: a. Recursively analyze the exp components. b. Curry to produce a ready-to-execute procedure. (define eval-while (lambda (exp env) (let ((pred (while-pred exp)) (body (while-body exp))) (letrec ((iter (lambda () (if (env-eval pred env) (begin (env-eval body env) (iter)) 'ok)))) iter)))) (define eval-while (lambda (exp env) (let ((pred (while-pred exp)) (body (while-body exp))) (letrec ((iter (lambda () (if (env-eval pred env) (begin (env-eval body env) (iter)) 'ok)))) iter)))) (define analyze-while (lambda (exp) (let ((pred (analyze (while-pred exp))) (body (analyze (while-body exp)))) (lambda (env) (letrec ((iter (lambda() (if (pred env) (begin (body env) (iter)) 'ok)))) (iter)))))) (define analyze-while (lambda (exp) (let ((pred (analyze (while-pred exp))) (body (analyze (while-body exp)))) (lambda (env) (letrec ((iter (lambda() (if (pred env) (begin (body env) (iter)) 'ok)))) (iter))))))
25
(define special-form? (lambda (exp) (or (quoted? exp)... (while? exp)))) (define special-form? (lambda (exp) (or (quoted? exp)... (while? exp)))) (define eval-special-form (lambda (exp env) (cond... ((while? exp) (eval-while exp env))))) (define eval-special-form (lambda (exp env) (cond... ((while? exp) (eval-while exp env))))) (define eval-while (lambda (exp env) (let ((pred (while-pred exp)) (body (while-body exp))) (letrec ((iter (lambda () (if (env-eval pred env) (begin (env-eval body env) (iter)) 'ok)))) (iter)))) (define eval-while (lambda (exp env) (let ((pred (while-pred exp)) (body (while-body exp))) (letrec ((iter (lambda () (if (env-eval pred env) (begin (env-eval body env) (iter)) 'ok)))) (iter)))) 25 Imperative Programming: Adding while – As a special form 1. Add to special-form?. Example 6 (cont’d): 2. Add an eval-special-form procedure 3. Add an eval-while procedure
26
26 Imperative Programming: Adding while – As a special form Example 6 (cont’d): Adding while to the compiler as a special form (define analyze-special-form (lambda (exp) (cond... ((while? exp) (analyze-while exp))))) (define analyze-special-form (lambda (exp) (cond... ((while? exp) (analyze-while exp))))) (define analyze-while (lambda (exp) (let ((pred (analyze (while-pred exp))) (body (analyze (while-body exp)))) (lambda (env) (letrec ((iter (lambda() (if (pred env) (begin (body env) (iter)) 'ok)))) (iter))))) (define analyze-while (lambda (exp) (let ((pred (analyze (while-pred exp))) (body (analyze (while-body exp)))) (lambda (env) (letrec ((iter (lambda() (if (pred env) (begin (body env) (iter)) 'ok)))) (iter))))) 1. Add to special-form?. 2. Make analysis of the expression components 2.Currying to produce a procedure ready for execution once an env is given. 1.Recursive analysis of analyze to the exp components. Rules 1,2 for adjusting the evaluator code to the analyzer code are not always applicable.
27
(define eval-while (lambda (exp env) (let ((pred (while-pred exp)) (body (while-body exp))) (if (env-eval pred env) (begin (env-eval body env) (eval-while exp env)) 'ok)))) (define eval-while (lambda (exp env) (let ((pred (while-pred exp)) (body (while-body exp))) (if (env-eval pred env) (begin (env-eval body env) (eval-while exp env)) 'ok)))) 27 Example 6 (cont’d): Adding while to the compiler as a special form o The code below can be used in env-eval, but cannot be easily translated to the analyzer by rules 1,2 used previously. o It involves a recursive call to eval-while which is performed during runtime. Analysis is performed during static time. o When using evaluator code for the purpose of adjusting it to the analyzer, eval must not be part of the computation, and should not produce new code. Imperative Programming: Adding while – As a special form
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.