Presentation is loading. Please wait.

Presentation is loading. Please wait.

Imperative Programming Chapter 6 1. Local State Real world software like: Banks Course grading system Are state systems. i.e. they change along time:

Similar presentations


Presentation on theme: "Imperative Programming Chapter 6 1. Local State Real world software like: Banks Course grading system Are state systems. i.e. they change along time:"— Presentation transcript:

1 Imperative Programming Chapter 6 1

2 Local State Real world software like: Banks Course grading system Are state systems. i.e. they change along time: for example: current balance and current grade. 2

3 What is Imperative Programming? “In computer science, imperative programming is a programming paradigm that describes computation in terms of statements that change a program state (Wikipedia)” Not better the FP! Just different 3

4 The Imperative Programming Model Imperative programming is characterized by: – Understanding variables as storage places (addresses) – Mutation operations – Operational semantics 4

5 Mutation in Racket Variable assignment: set! Box type Mutable data types (we will not use Racket’s built in, but create our own) 5

6 Variable Assignment Modification of value of a defined variable > (define my-list (list 1 2 3)) > my-list ’(1 2 3) > (set! my-list (list 1 2 4)) > my-list ’(1 2 4) > (set! a 4).. set!: assignment disallowed; cannot set variable before its definition 6

7 The Box Type Values are references (or pointers) for values that can be changed during computation. Constructor: box Selector: unbox Mutator: set-box! 7

8 Box Examples (1) (define a (box 7)) > (* 6 (unbox a)) 42 > a '#&7 > (set-box! a (+ (unbox a) 3)) > (* 6 (unbox a)) 60 8

9 Box Example (2): > (define circ-l (list (box 1) (box 2) (box 3))) > circ-l '(#&1 #&2 #&3) > (unbox (car circ-l)) 1 > (unbox (cadr circ-l)) 2 > (unbox (caddr circ-l)) 3 > (set-box! (caddr circ-l) circ-l) > circ-l #0='(#&1 #&2 #&#0#) > (unbox (caddr circ-l)) #0='(#&1 #&2 #&#0#) > (eq? circ-l (unbox (caddr circ-l))) #t 9

10 The Box type The Box type: Type constructor: BOX(T ) proceduretype name Value constructor: box [T → BOX(T )] Selector: unbox [BOX(T ) → T] Mutator: set-box! [BOX(T ) → Void] Identifier: box? [T → Boolean] Value equality: equal? [T1 ∗ T2 → Boolean] Identity equality: eq? [T1 ∗ T2 → Boolean] 10

11 Side Effects Side effects are "non-functional" There existence does not agree with the FP paradigm set! and set-box! are side effects procedure We have already seen two kinds of side effect procedures: define and the display procedure. Side effects procedures are applied for the sake of their side effects, and not for their returned value, void In imperative programming, it is meaningful to use sequences of expressions 11

12 State based modeling Defining objects with a modifiable private fields (local variables), and a set of accessors (selectors and mutators) that have controlled access to the object's private fields. All objects may have access to shared (static) variables. 12

13 Bank Account Withdrawal Example ;; Signature: withdraw(amount) ;; Purpose: Withdraw ’amount’ from a private ’balance’. ;; Type: [Number -> Number] ;; Post-condition: result = if balance@pre >= amount ;; then balance@pre - amount ;; else balance (define withdraw (let ((balance 100)) (lambda (amount) (if (>= balance amount) (begin (set! balance (- balance amount)) balance) (begin (display "Insufficient funds") (newline) balance))))) 13

14 > withdraw # > (withdraw 25) 75 > (withdraw 25) 50 > (withdraw 60) Insufficient funds 50 > (withdraw 15) 35 (define withdraw (let ((balance 100)) (lambda (amount) (if (>= balance amount) (begin (set! balance (- balance amount)) balance) (begin (display "Insufficient funds") (newline) balance))))) 14

15 Full Bank Account Example ;; Signature: make-account(balance) ;; Type: [Number -> [Symbol -> [Number -> Number]]] (define make-account (λ (balance) (let ((balance balance)) (letrec ((get-balance (λ (amount) balance)) (set-balance! (λ (amount) (set! balance amount))) (withdraw (λ (amount) (if (>= balance amount) (begin (set-balance! (- balance amount)) balance) (begin (display "Insufficient funds") (newline) balance)))) (deposit (λ (amount) (set-balance! (+ balance amount)) balance)) (dispatch (λ (m) (cond ((eq? m ’balance) get-balance) ((eq? m ’withdraw) withdraw) ((eq? m ’deposit) deposit) (else (error ’make-account "Unknown request: ~s" m)))))) dispatch)))) 15

16 > (define acc (make-account 100)) > acc # > ((acc ’withdraw) 50) 50 > ((acc ’withdraw) 60) Insufficient funds 50 > ((acc ’withdraw) 30) 20 > ((acc ’withdraw) 60) Insufficient funds 20 > (define acc2 (make-account 100)) > ((acc2 ’withdraw) 30) 70 > ((acc ’withdraw) 30) Insufficient funds 20 16

17 Mutable ADTs : Pair ; Type: [T1*T2 -> [Symbol -> Procedure]] ; The dispatch procedure returns procedures with different arities ; (Currying could help here). (define mpair (λ (x y) (letrec ((get-x (λ () x)) (get-y (λ () y)) (set-x! (λ (v) (set! x v))) (set-y! (λ (v) (set! y v))) (dispatch (lambda (m) (cond ((eq? m 'car) get-x) ((eq? m 'cdr) get-y) ((eq? m 'set-car!) set-x!) ((eq? m 'set-cdr!) set-y!) (else (error 'mpair "Undefined operation ~s" m)))))) dispatch))) 17

18 Mutable ADTs : Pair (define mutable-car (λ (z) ((z ’car)))) (define mutable-cdr (λ (z) ((z ’cdr)))) (define set-car! (lambda (z new-value) ((z ’set-car!) new-value))) (define set-cdr! (lambda (z new-value) ((z ’set-cdr!) new-value))) 18

19 Mutable ADTs : Pair > (define p1 (mpair 1 2)) > (mutable-car p1) 1 > (mutable-cdr p1) 2 > (set-car! p1 3) > (mutable-car p1) 3 > (set-cdr! p1 4) > (mutable-cdr p1) 4 > (mutable-cdr (set-cdr! p1 5)).. procedure application: expected procedure, given: # ; arguments were: ’cdr 19

20 Lazy Pair (define lazy-mpair (λ (x y) (let ((x (box x)) (y (box y))) (λ (sel) (sel x y))))) (define lazy-mcar (λ (z) (z (λ (x y) (unbox x))))) (define lazy-mcdr (λ (z) (z (λ (x y) (unbox y))))) (define lazy-set-car! (λ (z new-value) (z (λ (x y) (set-box! x new-value))))) (define lazy-set-cdr! (λ (z new-value) (z (λ (x y) (set-box! y new-value))))) 20

21 Lazy Pair > (define p2 (lazy-mpair 1 2)) > (lazy-mcar p2) 1 > (lazy-mcdr p2) 2 > (lazy-set-car! p2 3) > (lazy-mcar p2) 3 21

22 Value Equality vs. Identity Equality Since we have states, we can check state equality or identity. equal? – State (value) equality eq? – Object equality 22

23 Value Equality vs. Identity Equality > (define x (list (box 'a) (box 'b))) > (define y (list (car x) (box 'c) (box 'd))) > (define z (list (box 'a) (box 'c) (box 'd)) ) > (define w y) > (eq? y w); identity #t > (eq? y z) #f > (equal? y z) ; value equality #t > (equal? (car z) (car x)) #t > (eq? (car z) (car x)) #f 23

24 Evaluation of letrec Recall the problem we had: (define fact (lambda (n) (let ((iter (lambda (c p) (if (= c 0) p (iter (- c 1) (* c p)))))) (iter n 1)))) 24 Recursion call will not work

25 Evaluation of letrec Here’s a solution using imperative programming: (define fact (lambda (n) (let ((iter ‘unassigned)) (set! iter (lambda (c p) (if (= c 0) p (iter (- c 1) (* c p))))) (iter n 1)))) 25 Now iter is in the scope

26 Evaluation of letrec Now we unveil the secret of letrec … Its semantics cannot be explained in FP (let ((f1 ’unassigned)... (fn ’unassigned)) (set! f1 lambda-exp1)... (set! fn lambda-expn) e1... em)) 26

27 Extending the Environment Model The substitution model cannot support mutation Semantics of set-binding!(x,val, ) : 27

28 Extending the Environment Model Add set! Special operator: env−eval[(set! x e),env] = set−binding!(x,env−eval[e,env],env) Add Box type 28

29 Extending the Interpreter & Analyzer: Data Structures (define set-binding-in-env! (lambda (env var val) (letrec ((defined-in-env (lambda (var env) (if (empty-env? env) env (let ((b (get-value-of-variable (first-frame env) var))) (if (eq? b '_not-found) (defined-in-env var (enclosing-env env)) (first-boxed-frame env))))))) (let ((boxed-frame (defined-in-env var env))) (if (empty? boxed-frame) (error 'set! "variable not found") (let ((frame (unbox boxed-frame))) (set-box! boxed-frame (change-frame (make-binding var val) frame)))))))) 29 Recursive call Creates a new frame by adding a new binding

30 Extending the Interpreter & Analyzer: Data Structures (define change-frame (lambda (binding frame) (let ((bvar (binding-variable binding)) (bval (binding-value binding))) (change-sub frame bvar bval)))) (define change-sub (lambda (sub var value) (let ((vars (get-variables sub)) (values (get-values sub))) (if (member var vars) (make-sub (cons var vars) (cons value values)) (error 'change-sub "substitution is not defined on variable"))))) 30

31 Extending the Interpreter & Analyzer: Data Structures (define make-the-global-environment (lambda () (let* ((primitive-procedures (list (list 'car car) (list 'cdr cdr)... (list 'box box) (list 'unbox unbox) (list 'box? box?) (list 'set-box! set-box!)... 31

32 Extending the Interpreter & Analyzer: ASP (define letrec->let (lambda (exp) (letrec ((make-body (lambda (vars vals) (if (null? vars) (letrec-body exp) (make-sequence (make-assignment (car vars) (car vals)) (make-body (cdr vars) (cdr vals)))))) (make-bindings (lambda (vars) (map (lambda (var) (list var ’unassigned)) vars)))) (let* ((vars (letrec-variables exp)) (vals (letrec-initial-values exp)) ) (make-let (make-bindings vars) (make-body vars vals)))))) (define make-sequence (lambda (exp1 exp2) (cons exp1 exp2))) (define make-assignment (lambda (variable value) (attach-tag (list variable value) 'set!))) 32 Recursive call

33 Extending the Interpreter: env-eval (define eval-special-form (lambda (exp env) (cond... ((assignment? exp) (eval-assignment exp env))))) (define eval-assignment (lambda (exp env) (set-binding-in-env! env (assignment-variable exp) (env-eval (assignment-value exp) env)) 'ok)) 33

34 Extending the Analyzer (define analyze-assignment (lambda (exp) (let ((var (assignment-variable exp)) (val (analyze (assignment-value exp)))) (lambda (env) (set-binding-in-env! env var (val env)) ’ok)))) 34

35 Type Checking (set! x e) is well typed if e is well typed Typing rule for set! : For every: type assignment TA, expression e, and type expression S: If Tenv |- e:S, Tenv |- x:S, Then Tenv |- (set! x e):Void 35

36 Type Checking Axiom for box For every type environment Tenv and type expression S: Tenv |- box:[S -> BOX(S)] Tenv |- unbox:[BOX(S) -> S] Tenv |- set-box!:[BOX(S)*S -> Void] Tenv |- box?:[S -> Boolean] Tenv |- equal?:[BOX(S)*BOX(S) -> Boolean] Tenv |- eq?:[BOX(S)*BOX(S) -> Boolean] 36

37 Course summary 1/3 General concepts: semantics, types syntax, CFG(BNF), operational semantics, static analysis, renaming, substitution, interpretation(evaluation) polymorphic types, type safety 37

38 Course summary 2/3 functional programming model – function definition and application – special forms – derived expressions, ASP – apply-procedure, environments, analysis – high-order procedures – variable binding, lexical scoping (dynamic scoping) – static type inference – pattern matching 38

39 Course summary 3/3 logic programming model – axioms and queries – proof trees, unification, pruning imperative programming – mutable data types – state based execution of assignments – local state encapsulation Techniques: CPS, ADTs, Currying, Sequences, lazy lists 39

40 Thank you for listening. Good luck on your exams. 40

41 41


Download ppt "Imperative Programming Chapter 6 1. Local State Real world software like: Banks Course grading system Are state systems. i.e. they change along time:"

Similar presentations


Ads by Google