Overview
I would certainly appreciate suggestions of other extra credit activities (preferably via email).
How do you add to the end of a list?
Adding to the end of a list is inefficent, try to avoid it.
(append lst (list val))
If I’m building a list, how do I avoid adding to the end?
Add to the front.
If you are doing things recursively, the list may end up backwards. Reverse it.
For indices-of, how do I keep track of the position?
Have a helper that has multiple parameters, in addition to remaining have a
posthat represents the position in the original list.
Could we review tail recursion?
Sure.
Traditional (direct) recursion, we recurse and then do something with the result.
; count the number of odd values in a list
(define tally-odds
(lambda (lst)
(cond
[(null? lst)
0]
[(odd? (car lst))
(+ 1 (tally-odds (cdr lst)))]
[else
(tally-odds (cdr lst))])))
(tally-odds '(4 1 2 3 2))
=> (tally-odds '(1 2 3 2))
=> (+ 1 (tally-odds '(2 3 2)))
=> (+ 1 (tally-odds '(3 2)))
=> (+ 1 (+ 1 (tally-odds '(2))))
=> (+ 1 (+ 1 (tally-odds '())))
=> (+ 1 (+ 1 0))
=> (+ 1 1)
=> 2
Note that direct recursion builds up a lot of delayed work. Some people like to avoid building up that delayed work. We do that with helper recursion.
; Select all the odds in a list of values
(define select-odds
(lambda (lst)
(select-odds-helper lst null)))
(define select-odds-helper
(lambda (remaining odds-so-far)
(cond
[(null? remaining)
(reverse odds-so-far)]
[(odd? (car remaining))
(select-odds-helper (cdr remaining)
(cons (car remaining) odds-so-far))]
[else
(select-odds-helper (cdr remaining) odds-so-far)])))
Why do you make helpers to do tail recursion?
In most cases, you need a parameter to keep track of the “result so far”.
How do you pronounce words beginning with C
car (cah)
cdr (could-err)
cadr (cad err)
cddr (cuh did err)
Gloucester Marina
Could we write select-odds directly?
Sure.
(define select-odds
(lambda (lst)
(cond
[(null? lst)
null]
[(odd? (car lst))
(cons (car lst) (select-odds (cdr lst)))]
[else
(select-odds (cdr lst))])))
But we’ll build up a lot of cons’s.
Generalizing
(define select
(lambda (pred? lst)
(cond
[(null? lst)
null]
[(pred? (car lst))
(cons (car lst) (select pred? (cdr lst)))]
[else
(select pred? (cdr lst))])))
Plan time to work on homework with your partner.
Note “iota” is our old name for “range” (or at least the one-parameter “range”)
To add something to the front of a list, please use (cons val lst)
rather than (append (list val) lst).
Lab writeup: Problem 4
Defining iota
(define iota (lambda (n) (iota-helper 0 n))) (define iota-helper (lambda (start n) (if (= start n) null (cons start (iota-helper (+ start 1) n)))))
or
(define iota
(lambda (n)
(iota-helper (- n 1) null)))
(define iota-helper
(lambda (n so-far)
(if (< n 0)
so-far
(iota-helper (- n 1) (cons n so-far)))))