Programmering: Abstraktion och modellering VT 2015 TDDC74

advertisement
TDDC74 Programmering:
Abstraktion och modellering
VT 2015
Johannes Schmidt
Institutionen för datavetenskap
Linköpings universitet
Lecture 7
State and environment model
Part 1
• Muddy-card results
• Dugga1-solutions
• Functional programming, substitution model
• Applicative order versus normal order
• set!
• Substitution model does not work anymore
Part 2
• Introduction to environment diagrams
• SICP-Book chapter: 3
© Jalal Maleki,
2012
Muddy-card evaluation
Occurred more than once:
13 good labs and lab tasks
3 good labasses
4 good tutorials
4 all fine!
5 good examples on lectures
13 good lectures
4 good that lectures in English
3 good that slides are uploaded before the lectures
5 load up slides before the lectures
2 more examples in the lectures
3 learn how to handle the light
7 lectures too slow
5 lectures at good pace / too fast
3 more examples in tutorials
2 more time for tutorials / too many tasks
2 book in pdf
© Jalal Maleki,
2012
Part 1
Functional programming
Until now: functional programming (Lectures 1-3 + 4-6)
Functional programs = encodings of mathematical functions:
(define (factorial n)
(if (= n 1)
1
(* n (factorial (- n 1)))))
An expression always evaluates to the same value. E.g.
> (factorial 4)
24
> (factorial 4)
24
© Jalal Maleki,
2012
Functional programming
(define (factorial n)
(if (= n 1)
1
(* n (factorial (- n 1)))))
Can be understood with the substitution model:
(factorial 4)
(* 4 (factorial 3))
(* 4 (* 3 (factorial 2)))
(* 4 (* 3 (* 2 (factorial 1))))
(* 4 (* 3 (* 2 1)))
(* 4 (* 3 2))
(* 4 6)
24
© Jalal Maleki,
2012
A Remark on the substitution model
• Describes what happens when we apply a procedure on a
number of arguments
• Two variants of substitution orders
• Applicative order: evaluate the arguments, then go into the
procedure’s body with the evaluated arguments
• Normal order: go immediately into the procedure’s body with the
unevaluated arguments
© Jalal Maleki,
2012
Applicative order
Normal order
(square (* 4 2))
(square 8)
(* 8 8)
64
(square (* 4 2))
(* (* 4 2) (* 4 2))
(* 8 8)
64
A Remark on the substitution model
•
Applicative order: evaluate the arguments, then go into the procedure’s body
with the evaluated arguments
•
Normal order: go immediately into the procedure’s body with the
unevaluated arguments
(define (square x)
(* x x))
(define (sum-of-squares a b)
(+ (square a) (square b)))
(sum-of-squares (+ 2 1) (* 2 2))
Normal order ?
Applicative order ?
© Jalal Maleki,
2012
A Remark on the substitution model
(define (square x)
(* x x))
(define (sum-of-squares a b)
(+ (square a) (square b)))
(sum-of-squares (+ 2 1) (* 2 2))
Normal order
Applicative order
(sum-of-squares (+ 2 1) (* 2 2))
(sum-of-squares 3 4)
(+ (square 3) (square 4))
(+ (* 3 3) (* 4 4))
(+ 9 16)
25
; number of operations: 5
(sum-of-squares (+ 2 1) (* 2 2))
(+ (square (+ 2 1)) (square (* 2 2)))
(+ (* (+ 2 1) (+ 2 1)) (* (* 2 2) (* 2 2)))
(+ (* 3 3) (* 4 4))
(+ 9 16)
25
; number of operations: 7
© Jalal Maleki,
2012
Functional vs Imperative programming
Functional: An expression always evaluates to the same value
Imperative: we break with this rule
How? With
set!
• set! is used to change the value bound to a name
• Syntax: (set! <variable> <value>)
• Example: (set! x 5) (so called assignment)
© Jalal Maleki,
2012
Changing global state
(define value 0)
(define flip
(lambda ()
(set! value (- 1 value))
value)))
(flip) -> 1
(flip) -> 0
(flip) -> 1
© Jalal Maleki,
2012
What value does (set! ...) return?
Functional programming: Every expression evaluates to a value.
So what about set! ?
set! returns the value #<void>
Usually not displayed. You can display it with an explicit display instruction.
You can get the #<void>-value also by calling the function void:
> (set! x 5)
> (display (set! x 5))
#<void>
> (void)
> (display (void))
#<void>
Procedures that change values (assignments) are said to have
side effects. By convention they have the exklamation mark ! at the end
of their name. Side effect procedures often return #<void>.
© Jalal Maleki,
2012
Simulate a bank account
(define balance 100)
(define withdraw
(lambda (amount)
(set! balance (- balance amount))
balance))
>(withdraw 10)
90
>(withdraw 10)
80
>(withdraw 10)
70
© Jalal Maleki,
2012
Simulate two bank accounts?
(define balance 100)
(define withdraw
(lambda (amount)
(set! balance (- balance amount))
balance))
(define withdraw2
(lambda (amount)
(set! balance (- balance amount))
balance))
>(withdraw 10)
90
>(withdraw2 20)
70
© Jalal Maleki,
2012
Not nice!
Better:
make balance local
Simulate two bank accounts!
(define withdraw
(let ((balance 100))
(lambda (amount)
(set! balance (- balance amount))
balance)))
(define withdraw2
(let ((balance 100))
(lambda (amount)
(set! balance (- balance amount))
balance)))
>(withdraw 10)
90
>(withdraw2 20)
80
© Jalal Maleki,
2012
=> Changing local state
What is the difference?
(define withdrawA
(let ((balance 100))
(lambda (amount)
(set! balance (- balance amount))
balance)))
(define withdrawB
(lambda (amount)
(let ((balance 100))
(set! balance (- balance amount))
balance)))
© Jalal Maleki,
2012
Substitution model fails
• Substitution Model fails to work on procedures with side effects, that
is, when states are mutated
• For example, although the first argument of set! is a name, it has
other semantics (meaning) – it can not be substituted by a value.
(define (change state)
(set! state (not state)))
Try to substitute:
(change #f)
(set! #f (not #f)) !?
© Jalal Maleki,
2012
Why does the substitution model fail?
• Substitution is based on the notion that symbols are
names for values
• Using set! changes symbols to places where values
can be stored
• The value in such a place can change using
assignment with set!
• A new model of evaluation is needed: the
environment model
© Jalal Maleki,
2012
Download