Lecture 18
Imperative Programming
Logistics and Week Ahead
For some - Ethics Module 7 - Labor (if you're not signed up for an Ethics Discussion or missed yours earlier in the quarter you need to come see me ASAP)
Reminders / Announcements:
The story up until now
The story up until now
Change and effect
Calling functions for their effects
Imperative programming
Functional vs Imperative Programming
Advantages of imperative programming
#lang htdp/asl
All the code for the rest of the quarter will be in the Advanced Student Language with the exception of Ex.6
Effects in imperative programs
Effects in imperative programs
;; make-window!: string -> window
;; Make a new window
;; Effect: creates a new window
;; on the screen
(define (make-window! title)
… some magic code …)
Types and Type Signatures in imperative programs
-> number�-> string
number -> void�string -> void
Primitive imperatives
The simplest possible imperative
; void : -> void�
(void)
Assignment statements
(set! name new-value)
The next simplest imperative is assignment (set!) often read "set bang"
Why is this different from define?
Changing a global variable
(define count 0)
(define (increment!)
(set! count
(+ count 1)))
(define (clear!)
(set! count
0))
> count
0
> (increment!)
(void)
; means no value returned
> count
1
> (clear!)
(void)
> count
0
Composing imperatives
Composing imperatives
Sequencing imperatives
Sequencing with begin
(begin expression-1 expression-2 …)
Changing a global variable and returning a value
(define count 0)
(define (increment!)
(begin (set! count
(+ count 1))
count))
(define (clear!)
(begin (set! count
0)
count))
> count
0
> (increment!)
1
> count
1
> (clear!)
0
> count
0
Looping imperatives
Summing a list in imperative form
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! sum
(+ sum (first remaining)))
(set! remaining
(rest remaining))
(loop))))]
(loop)))
(sum-list '(1 2 3 4))
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! sum
(+ sum (first remaining)))
(set! remaining
(rest remaining))
(loop))))]
(loop)))
Variable | Value |
lst | '(1 2 3 4) |
(sum-list '(1 2 3 4))
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! sum
(+ sum (first remaining)))
(set! remaining
(rest remaining))
(loop))))]
(loop)))
Variable | Value |
lst | '(1 2 3 4) |
sum | 0 |
| |
| |
(sum-list '(1 2 3 4))
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! sum
(+ sum (first remaining)))
(set! remaining
(rest remaining))
(loop))))]
(loop)))
Variable | Value |
lst | '(1 2 3 4) |
sum | 0 |
remaining | '(1 2 3 4) |
| |
(sum-list '(1 2 3 4))
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! sum
(+ sum (first remaining)))
(set! remaining
(rest remaining))
(loop))))]
(loop)))
Variable | Value |
lst | '(1 2 3 4) |
sum | 0 |
remaining | '(1 2 3 4) |
loop | (λ () …) |
(sum-list '(1 2 3 4))
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! sum
(+ sum (first remaining)))
(set! remaining
(rest remaining))
(loop))))]
(loop)))
Variable | Value |
lst | '(1 2 3 4) |
sum | 0 |
remaining | '(1 2 3 4) |
loop | (λ () …) |
(sum-list '(1 2 3 4))
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! sum
(+ sum (first remaining)))
(set! remaining
(rest remaining))
(loop))))]
(loop)))
Variable | Value |
lst | '(1 2 3 4) |
sum | 0 |
remaining | '(1 2 3 4) |
loop | (λ () …) |
(sum-list '(1 2 3 4))
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! sum
(+ sum (first remaining)))
(set! remaining
(rest remaining))
(loop))))]
(loop)))
Variable | Value |
lst | '(1 2 3 4) |
sum | 1 |
remaining | '(1 2 3 4) |
loop | (λ () …) |
(sum-list '(1 2 3 4))
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! sum
(+ sum (first remaining)))
(set! remaining
(rest remaining))
(loop))))]
(loop)))
Variable | Value |
lst | '(1 2 3 4) |
sum | 1 |
remaining | '(2 3 4) |
loop | (λ () …) |
(sum-list '(1 2 3 4))
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! sum
(+ sum (first remaining)))
(set! remaining
(rest remaining))
(loop))))]
(loop)))
Variable | Value |
lst | '(1 2 3 4) |
sum | 1 |
remaining | '(2 3 4) |
loop | (λ () …) |
(sum-list '(1 2 3 4))
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! sum
(+ sum (first remaining)))
(set! remaining
(rest remaining))
(loop))))]
(loop)))
Variable | Value |
lst | '(1 2 3 4) |
sum | 1 |
remaining | '(2 3 4) |
loop | (λ () …) |
(sum-list '(1 2 3 4))
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! sum
(+ sum (first remaining)))
(set! remaining
(rest remaining))
(loop))))]
(loop)))
Variable | Value |
lst | '(1 2 3 4) |
sum | 3 |
remaining | '(2 3 4) |
loop | (λ () …) |
(sum-list '(1 2 3 4))
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! sum
(+ sum (first remaining)))
(set! remaining
(rest remaining))
(loop))))]
(loop)))
Variable | Value |
lst | '(1 2 3 4) |
sum | 3 |
remaining | '(3 4) |
loop | (λ () …) |
(sum-list '(1 2 3 4))
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! sum
(+ sum (first remaining)))
(set! remaining
(rest remaining))
(loop))))]
(loop)))
Variable | Value |
lst | '(1 2 3 4) |
sum | 3 |
remaining | '(3 4) |
loop | (λ () …) |
(sum-list '(1 2 3 4))
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! sum
(+ sum (first remaining)))
(set! remaining
(rest remaining))
(loop))))]
(loop)))
Variable | Value |
lst | '(1 2 3 4) |
sum | 3 |
remaining | '(3 4) |
loop | (λ () …) |
(sum-list '(1 2 3 4))
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! sum
(+ sum (first remaining)))
(set! remaining
(rest remaining))
(loop))))]
(loop)))
Variable | Value |
lst | '(1 2 3 4) |
sum | 6 |
remaining | '(3 4) |
loop | (λ () …) |
(sum-list '(1 2 3 4))
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! sum
(+ sum (first remaining)))
(set! remaining
(rest remaining))
(loop))))]
(loop)))
Variable | Value |
lst | '(1 2 3 4) |
sum | 6 |
remaining | '(4) |
loop | (λ () …) |
(sum-list '(1 2 3 4))
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! sum
(+ sum (first remaining)))
(set! remaining
(rest remaining))
(loop))))]
(loop)))
Variable | Value |
lst | '(1 2 3 4) |
sum | 6 |
remaining | '(4) |
loop | (λ () …) |
(sum-list '(1 2 3 4))
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! sum
(+ sum (first remaining)))
(set! remaining
(rest remaining))
(loop))))]
(loop)))
Variable | Value |
lst | '(1 2 3 4) |
sum | 6 |
remaining | '(4) |
loop | (λ () …) |
(sum-list '(1 2 3 4))
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! sum
(+ sum (first remaining)))
(set! remaining
(rest remaining))
(loop))))]
(loop)))
Variable | Value |
lst | '(1 2 3 4) |
sum | 10 |
remaining | '(4) |
loop | (λ () …) |
(sum-list '(1 2 3 4))
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! sum
(+ sum (first remaining)))
(set! remaining
(rest remaining))
(loop))))]
(loop)))
Variable | Value |
lst | '(1 2 3 4) |
sum | 10 |
remaining | '() |
loop | (λ () …) |
(sum-list '(1 2 3 4))
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! sum
(+ sum (first remaining)))
(set! remaining
(rest remaining))
(loop))))]
(loop)))
Variable | Value |
lst | '(1 2 3 4) |
sum | 10 |
remaining | '() |
loop | (λ () …) |
(sum-list '(1 2 3 4))
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! sum
(+ sum (first remaining)))
(set! remaining
(rest remaining))
(loop))))]
(loop)))
Variable | Value |
lst | '(1 2 3 4) |
sum | 10 |
remaining | '() |
loop | (λ () …) |
(sum-list '(1 2 3 4))
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! sum
(+ sum (first remaining)))
(set! remaining
(rest remaining))
(loop))))]
(loop)))
Variable | Value |
lst | '(1 2 3 4) |
sum | 10 |
remaining | '() |
loop | (λ () …) |
Imperative bugs
Imperatives can be tricky
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! remaining
(rest remaining))
(set! sum
(+ sum (first remaining)))
(loop))))]
(loop)))
(sum-list (list 1 2 3 4))
Imperatives can be tricky
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! remaining
(rest remaining))
(set! sum
(+ sum (first remaining)))
(loop))))]
(loop)))
(sum-list (list 1 2 3 4))
first: expects a non-empty list; given: '()
What happened?
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! remaining
(rest remaining))
(set! sum
(+ sum (first remaining)))
(loop))))]
(loop)))
(sum-list (list 1 2 3 4))
Variable | Value |
lst | '(1 2 3 4) |
What happened?
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! remaining
(rest remaining))
(set! sum
(+ sum (first remaining)))
(loop))))]
(loop)))
(sum-list (list 1 2 3 4))
Variable | Value |
lst | '(1 2 3 4) |
sum | 0 |
What happened?
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! remaining
(rest remaining))
(set! sum
(+ sum (first remaining)))
(loop))))]
(loop)))
(sum-list (list 1 2 3 4))
Variable | Value |
lst | '(1 2 3 4) |
sum | 0 |
remaining | '(1 2 3 4) |
What happened?
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! remaining
(rest remaining))
(set! sum
(+ sum (first remaining)))
(loop))))]
(loop)))
(sum-list (list 1 2 3 4))
Variable | Value |
lst | '(1 2 3 4) |
sum | 0 |
remaining | '(1 2 3 4) |
loop | (λ () …) |
What happened?
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! remaining
(rest remaining))
(set! sum
(+ sum (first remaining)))
(loop))))]
(loop)))
(sum-list (list 1 2 3 4))
Variable | Value |
lst | '(1 2 3 4) |
sum | 0 |
remaining | '(1 2 3 4) |
loop | (λ () …) |
What happened?
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! remaining
(rest remaining))
(set! sum
(+ sum (first remaining)))
(loop))))]
(loop)))
(sum-list (list 1 2 3 4))
Variable | Value |
lst | '(1 2 3 4) |
sum | 0 |
remaining | '(1 2 3 4) |
loop | (λ () …) |
What happened?
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! remaining
(rest remaining))
(set! sum
(+ sum (first remaining)))
(loop))))]
(loop)))
(sum-list (list 1 2 3 4))
Variable | Value |
lst | '(1 2 3 4) |
sum | 0 |
remaining | '(2 3 4) |
loop | (λ () …) |
What happened?
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! remaining
(rest remaining))
(set! sum
(+ sum (first remaining)))
(loop))))]
(loop)))
(sum-list (list 1 2 3 4))
Variable | Value |
lst | '(1 2 3 4) |
sum | 2 |
remaining | '(2 3 4) |
loop | (λ () …) |
What happened?
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! remaining
(rest remaining))
(set! sum
(+ sum (first remaining)))
(loop))))]
(loop)))
(sum-list (list 1 2 3 4))
Variable | Value |
lst | '(1 2 3 4) |
sum | 2 |
remaining | '(2 3 4) |
loop | (λ () …) |
What happened?
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! remaining
(rest remaining))
(set! sum
(+ sum (first remaining)))
(loop))))]
(loop)))
(sum-list (list 1 2 3 4))
Variable | Value |
lst | '(1 2 3 4) |
sum | 2 |
remaining | '(2 3 4) |
loop | (λ () …) |
What happened?
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! remaining
(rest remaining))
(set! sum
(+ sum (first remaining)))
(loop))))]
(loop)))
(sum-list (list 1 2 3 4))
Variable | Value |
lst | '(1 2 3 4) |
sum | 2 |
remaining | '(3 4) |
loop | (λ () …) |
What happened?
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! remaining
(rest remaining))
(set! sum
(+ sum (first remaining)))
(loop))))]
(loop)))
(sum-list (list 1 2 3 4))
Variable | Value |
lst | '(1 2 3 4) |
sum | 5 |
remaining | '(3 4) |
loop | (λ () …) |
What happened?
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! remaining
(rest remaining))
(set! sum
(+ sum (first remaining)))
(loop))))]
(loop)))
(sum-list (list 1 2 3 4))
Variable | Value |
lst | '(1 2 3 4) |
sum | 5 |
remaining | '(3 4) |
loop | (λ () …) |
What happened?
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! remaining
(rest remaining))
(set! sum
(+ sum (first remaining)))
(loop))))]
(loop)))
(sum-list (list 1 2 3 4))
Variable | Value |
lst | '(1 2 3 4) |
sum | 5 |
remaining | '(3 4) |
loop | (λ () …) |
What happened?
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! remaining
(rest remaining))
(set! sum
(+ sum (first remaining)))
(loop))))]
(loop)))
(sum-list (list 1 2 3 4))
Variable | Value |
lst | '(1 2 3 4) |
sum | 5 |
remaining | '(4) |
loop | (λ () …) |
What happened?
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! remaining
(rest remaining))
(set! sum
(+ sum (first remaining)))
(loop))))]
(loop)))
(sum-list (list 1 2 3 4))
Variable | Value |
lst | '(1 2 3 4) |
sum | 5 |
remaining | '(4) |
loop | (λ () …) |
What happened?
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! remaining
(rest remaining))
(set! sum
(+ sum (first remaining)))
(loop))))]
(loop)))
(sum-list (list 1 2 3 4))
Variable | Value |
lst | '(1 2 3 4) |
sum | 5 |
remaining | '(4) |
loop | (λ () …) |
What happened?
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! remaining
(rest remaining))
(set! sum
(+ sum (first remaining)))
(loop))))]
(loop)))
(sum-list (list 1 2 3 4))
Variable | Value |
lst | '(1 2 3 4) |
sum | 5 |
remaining | '(4) |
loop | (λ () …) |
What happened?
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! remaining
(rest remaining))
(set! sum
(+ sum (first remaining)))
(loop))))]
(loop)))
(sum-list (list 1 2 3 4))
Variable | Value |
lst | '(1 2 3 4) |
sum | 5 |
remaining | '() |
loop | (λ () …) |
What happened?
(define (sum-list lst)
(local [(define sum 0)
(define remaining lst)
(define (loop)
(if (empty? remaining)
sum
(begin (set! remaining
(rest remaining))
(set! sum
(+ sum (first remaining)))
(loop))))]
(loop)))
(sum-list (list 1 2 3 4))
Variable | Value |
lst | '(1 2 3 4) |
sum | 5 |
remaining | '() |
loop | (λ () …) |
Higher-order imperatives
Looping as a sequencing primitive
(for-each func a-list)
Cleaning up the code
(define (sum-list lst)
(local [(define sum 0)]
(begin (for-each (λ (element)
(set! sum (+ sum element)))
lst)
sum)))
Example: (sum-list '(1 2 3 4))
(define (sum-list lst)
(local [(define sum 0)]
(begin (for-each (λ (element)
(set! sum (+ sum element)))
lst)
sum)))
Example: (sum-list '(1 2 3 4))
(define (sum-list lst)
(local [(define sum 0)]
(begin (for-each (λ (element)
(set! sum (+ sum element)))
lst)
sum)))
Variable | Value |
lst | '(1 2 3 4) |
Example: (sum-list '(1 2 3 4))
(define (sum-list lst)
(local [(define sum 0)]
(begin (for-each (λ (element)
(set! sum (+ sum element)))
lst)
sum)))
Variable | Value |
lst | '(1 2 3 4) |
sum | 0 |
Example: (sum-list '(1 2 3 4))
(define (sum-list lst)
(local [(define sum 0)]
(begin (for-each (λ (element)
(set! sum (+ sum element)))
lst)
sum)))
Variable | Value |
lst | '(1 2 3 4) |
sum | 0 |
Example: (sum-list '(1 2 3 4))
(define (sum-list lst)
(local [(define sum 0)]
(begin (for-each (λ (element)
(set! sum (+ sum element)))
lst)
sum)))
Variable | Value |
lst | '(1 2 3 4) |
sum | 1 |
Example: (sum-list '(1 2 3 4))
(define (sum-list lst)
(local [(define sum 0)]
(begin (for-each (λ (element)
(set! sum (+ sum element)))
lst)
sum)))
Variable | Value |
lst | '(1 2 3 4) |
sum | 3 |
Example: (sum-list '(1 2 3 4))
(define (sum-list lst)
(local [(define sum 0)]
(begin (for-each (λ (element)
(set! sum (+ sum element)))
lst)
sum)))
Variable | Value |
lst | '(1 2 3 4) |
sum | 6 |
Example: (sum-list '(1 2 3 4))
(define (sum-list lst)
(local [(define sum 0)]
(begin (for-each (λ (element)
(set! sum (+ sum element)))
lst)
sum)))
Variable | Value |
lst | '(1 2 3 4) |
sum | 10 |
Example: (sum-list '(1 2 3 4))
(define (sum-list lst)
(local [(define sum 0)]
(begin (for-each (λ (element)
(set! sum (+ sum element)))
lst)
sum)))
Variable | Value |
lst | '(1 2 3 4) |
sum | 10 |
Comparison of�functional and imperative programming
sum-list in functional and imperative form
Functional version:
(define (sum-list/func a-list)
(if (empty? a-list)
0
(+ (first a-list)
(sum-list/func
(rest a-list)))))
Imperative version:
(define (sum-list a-list)
(local [(define sum 0)
(define rem a-list)
(define (loop)
(if (empty? rem)
sum
(begin (set! sum
(+ sum
(first rem)))
(set! rem
(rest rem))
(loop))))]
(loop)))
sum-list in functional and imperative form
Functional version:
(define (sum-list/func a-list)
(if (empty? a-list)
0
(+ (first a-list)
(sum-list/func
(rest a-list)))))
Imperative version:
(define (sum-list a-list)
(local [(define sum 0)
(define rem a-list)
(define (loop)
(if (empty? rem)
sum
(begin (set! sum
(+ sum
(first rem)))
(set! rem
(rest rem))
(loop))))]
(loop)))
More focused on what to compute
More focused on how to compute it
sum-list in functional and imperative form
Functional version:
(define (sum-list/func a-list)
(if (empty? a-list)
0
(+ (first a-list)
(sum-list/func
(rest a-list)))))
Imperative version:
(define (sum-list a-list)
(local [(define sum 0)]
(begin (for-each (λ (element)
(set! sum
(+ sum element)))
a-list)
sum)))
More focused on what to compute
More focused on how to compute it
What have we changed?
Rules of computation in ASL
Look at the expression
Special cases: New Imperative Additions
If it starts with λ or lambda:
(λ (name1 … namelast) result-expression)
If it starts with the the word local
(local [(define name1 value1) � …� (define namelast valuelast)]� result-expression)
Imperative special forms
If it starts with set!
(set! name value-expression)
If it starts with the the word begin
(begin expressions …)