Hint: if you're using Dr Scheme, set language to MzScheme (since
other languages are too different from MIT Scheme)
Examples
-- (list 1 2 3)
-- (list)
-- (cons 1 null)
How are lists displayed?
-- list containing 1, 2, 3 shown as (1 2 3)
-- don't confuse with a combination expression!
-- it's an external representation, not an expression
How to take a list apart
-- first and rest, with funny names:
car: list<A> -> A
car: list<A> -> list<A>
Examples
-- (car (list 1 2 3))
-- (cdr (list 1 2 3))
-- (car (cdr (list 1 2 3)))
-- (car (car (list 1 2 3)))
Examples
(define p (list 1 2 3))
(length p)
(append p p)
(length (append p p))
(length null)
Exercise
-- write your own version of length recursively
-- write append
-- write reverse
Examples
-- (filter (list 1 2 3) is-odd)
-- (map inc (list 1 2 3))
-- (map is-odd (list 1 2 3))
Exercise
-- write a filter that eliminates null lists from the list
-- write a function that doubles all elements of a list
-- write map
-- write filter
Examples
-- (map (lambda (s) (string-append s "!")) ht)
-- (filter (list (list) (list 1 2)) null?)
-- (map list (list 1 2 3))
List structure
-- a list is built as a bunch of cons cells strung together like a
necklace
-- there is a special value null used to terminate lists
BPDs, box and pointer diagrams)
-- must have an arrow pointing to the object itself
-- cons cell has two parts
-- primitive objects drawn in a circle
-- null drawn with line through half of cons cell
Heterogeneous Lists
-- can make lists in which elements have different types
-- (list 1 "hello")
-- (list 1 (list 2))
-- our type notation can't handle this
Improper Lists
-- (cons 1 2) is legal in Scheme
-- but doesn't make a list!
-- sometimes called "improper list" by those who disapprove
What makes a list?
-- can keep applying cdr, and always get a list or null
-- equivalently: null is a list and if (cdr x) is a list, so is x
Draw BPDs for
-- (list 1 2 3)
-- (list (list 1) (list 2 3))
-- (cons (cons 1 2) (cons 3 4))
-- (cons 1 (cons 2 null))
-- which is a list?
(define (inc i) (+ i 1))
(define (dec i) (- i 1))
(define (is-odd n)
(cond ((= n 0) #f)
((= n 1) #t)
(else (is-odd (- n 2)))))
(define (append p q)
(if (null? p) q (cons (car p) (append (cdr p) q))))
(define (reverse p)
(if (null? p)
p
(append (reverse (cdr
p)) (list (car p)))))
(define (map f p)
(if (null? p)
p
(cons (f (car p)) (map f (cdr p)))))
(define (filter p f)
(if (null? p)
p
(let ((first (car p))
(rest (filter (cdr p) f)))
(if (f first)
(cons first rest)
rest))))