Lecture 20
Mutability and Scope
Logistics and Week Ahead
Next week (for some - Ethics Module 8 - Sustainability )
If you are not registered or did not attend an ethics discussion section at some point this quarter, today is the last day you can speak with me (or email me) to fix that.
Reminders:
Kinds of Variables
Global variables
Local variables
Local defines
(define (my-length list)
(local [(define (loop count remaining)
(if (empty? remaining) count
(loop (+ count 1)
(rest remaining))))]
(loop 0 list)))
(my-length '(1 2 3 4))
Local variables are great!
No local variables
(define (my-length list)
(loop 0 list))
(define (loop count remaining)
(if (empty? remaining)
count
(loop (+ count 1)
(rest remaining))))
(define (add-list list)
(loop 0 list))
(define (loop sum remaining)
(if (empty? remaining)
sum
(loop (+ sum (first remaining))
(rest remaining))))
With local variables
(define (my-length list)
(local [(define (loop count remaining)
(if (empty? remaining) count
(loop (+ count 1)
(rest remaining))))]
(loop 0 list)))
(define (add-list list)
(local [(define (loop sum remaining)
(if (empty? remaining) sum
(loop (+ sum (first remaining))
(rest remaining))))]
(loop 0 list)))
Mutability
Mutable variables
Immutable variables
Immutable data objects
Mutable data objects
Variable scope
(define x 10)
(define (foo x)
(+ x x))
(define (bar x)
(* x x))
(define (baz z)
(+ z x))
What is the "scope" of a variable?
(define x 10)
(define (foo x)
(+ x x))
(define (bar x)
(* x x))
(define (baz z)
(+ z x))
How does the computer know which x we mean?
> (foo 5)
⇒((λ (x) (+ x x)) 5)
⇒(<add> 5 5)
⇒10
> (baz 5)
⇒((λ (z) (+ z x)) 5)
⇒(+ 5 x)
⇒(<add> 5 10)
⇒15
Notice how foo and baz get different x's!
Scope is both space and time
(define (my-length list)
(if (empty? list)
0
(+ 1
(my-length (rest list)))))
> (my-length '(1 2 3))
⇒ (+ 1 (my-length '(2 3)))
⇒ (+ 1 (+ 1 (my-length '(3))))
⇒ (+ 1 (+ 1 (+ 1 (my-length '()))))
⇒ 3
list1 = '(1 2 3)
list2 = '(2 3)
list3 = '(3)
list4 = '()
Shadowing
A confusing way to square numbers:
(define (evil-square x)
(local [(define + *)]
(+ x x)))
Finding Beatles Albums:
(define (artist-albums artist list)
(filter (λ (list)
(= (album-artist list)
artist))
list))
Why is this important for imperatives?
With the ability to update variables, we need to know which variable we're actually updating!
(define x "hello")
(local [(define x 1)]
(set! x (+ x 1)))
x
(define y "hello")
(local [(define y 1)]
(begin (set! y (+ y 1))
y))
y
More Examples
(define a 4)
"example 1"
(local [(define x 1)
(define y 2)
(define z 3)]
(+ x y z)) ; only uses variables inside the local def
"example 2"
(local [(define x 1)
(define y 2)
(define z 3)]
(+ x y z a)) ; uses variables inside local def +
; global (a)
"example 3"
(local [(define x 1)
(define y 2)
(define z 3)
(define (foo q)
(* q 10))]
(+ x y z (foo y) a)) ; adds a function definition
; inside of local
"example 4"
(local [(define x 1)
(define y 2)
(define z 3)
(define (foo x)
(* x 10))]
(+ x y z (foo y) a)) ; adds a conflict of x inside of local
"example 5"
(local [(define x 1)
(define y 2)
(define z 3)
(define a 5)
(define (foo x)
(* x 10))]
(+ x y z (foo y) a)) ; adds a conflict of a inside of local
"example 6"
(local [(define x 1)
(define y 2)
(define z 3)
(define a 5)
(define (foo x)
(* x y))]
(+ x y z (foo z) a)) ; uses local y within local definitions
More imperative practice in lecture files…