Lecture 20 Slides - Scope and Mutability

1 of 13

Lecture 20

Mutability and Scope

2 of 13

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.

  • Monday - Mutation and Sub-types (Ex 7 posted)
  • Wednesday - Methods (Pre-Recorded + MQ15) + Tutorial 8
  • Friday - Object-Oriented Programming (MQ 16) (Ex 7 Due)

Reminders:

  • Snake DOES NOT use imperatives! (#lang htdp/isl+)
    • Built-in check-expects DO NOT guarantee correct game behavior - PLAY THE GAME!
    • Ex 6 is due tonight
  • Ethics Module 7 reflections due Sunday at 11:59pm

3 of 13

Kinds of Variables

Global variables

  • Variables that aren't inside of function or locals
  • Can be used by the entire program

Local variables

  • Variables that are inside a function
    • Arguments
    • Variables created with a local
  • Only usable within that expression
  • There can be multiple different “flavors” of local

4 of 13

Local defines

  • You can use local to put define statements inside of a function
  • Makes local variables
  • Can be used to make local functions, including recursive ones

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

5 of 13

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

6 of 13

Mutability

Mutable variables

  • Variables that can be mutated (changed/updated)
  • Basically anything created using the define special form

Immutable variables

  • Variables that cannot be mutated (changed/updated)
  • Function arguments (inputs) are immutable
  • set! is a function that allows us to mutate a variable's value if it is mutable.

Immutable data objects

  • Most of our data types cannot be directly mutated: lists, strings, etc.

Mutable data objects

  • Starting next week, all of our structs will be directly mutable

7 of 13

Variable scope

  • Scope is the region of the program over which the variable is visible

  • Substitution model guarantees
    • Global variables are "visible" throughout the program
    • Function arguments are visible only within the function (and are immutable)

(define x 10)

(define (foo x)

(+ x x))

(define (bar x)

(* x x))

(define (baz z)

(+ z x))

8 of 13

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!

9 of 13

Scope is both space and time

  • Two list variables:
    • A global variable (the function list)
    • A local variable (the argument to my-length)
  • But my-length is recursive
    • So there are many list variables
    • One for every call to my-length!
  • These are all different variables!
    • But they have the same name (to you at least)
    • Just like there can be two people named Bob

(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 = '()

10 of 13

Shadowing

  • Shadowing is when you define a local variable with the same name as:
    • A global variable
    • Local variable in the surrounding scope

  • The new variable shadows the old variable
    • Covers it up
    • So that the program within the scope of the new variable can't use the old one

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

11 of 13

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

12 of 13

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

13 of 13

More imperative practice in lecture files…