1 / 41

Imperative Programming Chapter 6

Imperative Programming Chapter 6. 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. What is Imperative Programming?.

jatin
Download Presentation

Imperative Programming Chapter 6

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Imperative ProgrammingChapter 6

  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.

  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

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

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

  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

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

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

  9. Box Example (2): > (definecirc-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

  10. The Box type The Box type: Type constructor: BOX(T ) procedure type 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]

  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

  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.

  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)))))

  14. > withdraw #<procedure: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)))))

  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))))

  16. > (define acc (make-account 100)) > acc #<procedure:dispatch> > ((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

  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)))

  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)))

  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: #<void>; arguments were: ’cdr

  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)))))

  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

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

  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

  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)))) 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)))) 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))

  27. Extending the Environment Model • The substitution model cannot support mutation • Semantics ofset-binding!(x,val,<f1,...,fn>) :

  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

  29. Extending the Interpreter & Analyzer:Data Structures (define set-binding-in-env! (lambda (envvarval) (letrec ((defined-in-env (lambda (varenv) (if (empty-env? env) env (let ((b (get-value-of-variable (first-frame env) var))) (if (eq? b '_not-found) (defined-in-envvar (enclosing-envenv)) (first-boxed-frame env))))))) (let ((boxed-frame (defined-in-envvarenv))) (if (empty? boxed-frame) (error 'set! "variable not found") (let ((frame (unbox boxed-frame))) (set-box! boxed-frame (change-frame (make-binding varval) frame)))))))) 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 bvarbval)))) (define change-sub (lambda (sub var value) (let ((vars (get-variables sub)) (values (get-values sub))) (if (member varvars) (make-sub (cons varvars) (cons value values)) (error 'change-sub "substitution is not defined on variable")))))

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

  32. Extending the Interpreter & Analyzer:ASP (define letrec->let (lambda (exp) (letrec ((make-body (lambda (varsvals) (if (null? vars) (letrec-body exp) (make-sequence (make-assignment (car vars) (car vals)) (make-body (cdrvars) (cdrvals)))))) (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 varsvals)))))) (define make-sequence (lambda (exp1 exp2) (cons exp1 exp2))) (define make-assignment (lambda (variable value) (attach-tag (list variable value) 'set!))) 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))

  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! envvar (valenv)) ’ok))))

  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

  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]

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

  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

  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

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

More Related