# CS3L OaW Lecture 10 : CAL (Cons Append List)

## Lists, aka "CAL : Cons, Append & List"

### Overview

• We're going to motivate the need for lists by talking about the limitations of sentences.
• Sentences can't have nested sentences or booleans & procedures in it. E.g.,
```: (define an-illegal-sentence
'(cs3 is great (but that is my (dans) opinion) and fun))

: (define another-illegal-sentence
'(#f #t #t))```
• Lists can be thought of by thinking of sentences but relaxing both those constraints...
• Lists can be created by hand, and can contain any number of atoms
```: '(yo whassup GoBears CS3isNumber 1)
==> (yo whassup gobears cs3isnumber 1)```
• Just as expressions can be simple or complex...
```: (+ 3 5)
==> 8

: (+ 1 (/ 4 2) (+ (- 5 1) (remainder (truncate 4.9) 3)))
==> 8```
• ...lists can be simple or complex too! (in fact, if you look closely, you'll see the expression above was really a list in itself, ooooh!). In contrast, sentences can only be simple (i.e., not nested).
```: (define simple '(1 2 3 4) )
==> simple

: simple  ;; list OR sentence
==> (1 2 3 4)

: (define complex '(a (b c) () ((d)) ) )
==> complex

: complex  ;; only lists can be complex
==> (a (b c) ((d)))```
• Simple is a list of four elements, the atoms 1, 2, 3 and 4
• Complex is a list of three elements, the first the atom a, the second a list (containing two elements, atoms b and c), and the third is a list (nested, containing one element, which itself is a list containing d)

### Data Structures

• Lists are often used as data structures, to store information
```: (define meals
'((breakfast (3 rasberry poptarts)
(7 eggs)
(5 mango smoothies))
(3 burritos)
(4 yoo-hoos))
(dinner    (3 pepto-bismol)
(2 nyquil)
(1 pearl milk tea))))

: meals
==> ((breakfast (3 rasberry poptarts)
(7 eggs)
(5 mango smoothies))
(3 burritos)
(4 yoo-hoos))
(dinner    (3 pepto-bismol)
(2 nyquil)
(1 pearl milk tea)))```

### Selectors and Constructors Overview

• Whenever we discuss a new data type, we need to discuss the selectors and constructors.
• The primary selectors and constructors are (you can also find these in the back cover of the book):
• cons, list, append, car, cdr, length, null?, list?, list-ref
• We can use the variable L when using lists (uppercase L is better than lowercase l which looks like the number one ... 1), just as we used s for sentences.

### Constructors

• Lists can contain no elements, this is called the null list (same printed representation as the empty sentence)
```: '()
==> ()```
• They can be created explicitly as we have seen so far
```: '(this is a list)
==> (this is a list)```
• ...or they can be created through constructors:
• (cons element list)
• Returnslist with element inserted at the start
• (Note that in general, the second argument to cons can be anything, but NOT IN CS3 ... in this class, the second argument to cons MUST BE a list)
• (append list1 list2 ... listn)
• Returns the list formed by concatenating the elements of list1 ... listn
• (list el1 el2 ... eln)
• returns the list (el1 el2 ... eln)
• Examples:
```: (cons 'cs3 '())
==> (cs3)

: (cons 'love (cons 'cs3 '()))
==> (love cs3)

: (cons 'i (cons 'love (cons 'cs3 '())))
==> (i love cs3)

: (cons '(1 2) '(3 4))
==> ((1 2) 3 4)

: (list 1 2 5 'three-sir 3)
==> (1 2 5 three-sir 3)

: (list 1 2 5 '(3 sir) 3)
==> (1 2 5 (3 sir) 3)

: (append '(1 2) '(3 4))
==> (1 2 3 4)

: (append '(1) '(2 (3)) '() '(4 5 6) '(((7))) )
==> (1 2 (3) 4 5 6 ((7)))```
• Ways you can think about it:
• cons stuffs its first argument into the paren of the second
• list just dissolves the word list
• append dissolves parenthesis around each element and itself
• And, taken together, these are the CAL functions (Cons Append List)!

### Selectors

• The primary selectors are car and cdr:
• (car list)
• same as first, but for lists - i.e., return the first element of the list, if there is one.
• (cdr list)
• same as butfirst (pronounced "could-er"), but for lists - i.e., return all but the first element of the list.
```: (define my-list
'(cs3 is great (but that is my (dans) opinion) and fun))

: my-list
==> (cs3 is great (but that is my (dans) opinion) and fun)

: (car my-list)
==> cs3

: (cdr my-list)
==> (is great (but that is my (dans) opinion) and fun)

: (cdr (cdr my-list))
==> (great (but that is my (dans) opinion) and fun)

: (cdr (cdr (cdr my-list)))
==> ((but that is my (dans) opinion) and fun)

: (cdr (cdr (cdr (cdr my-list))))
==> (and fun)```
• It is an error to request the car or cdr of a null list:
```: (car '())
*** ERROR -- PAIR expected
(car '())

: (cdr '())
*** ERROR -- PAIR expected
(cdr '())```
• There are also built-in shortcuts which allow you to combine several (up to 4) consecutive cars and cdrs together:
```: my-list
==> (cs3 is great (but that is my (dans) opinion) and fun)

: (car (cdr (cdr (cdr my-list))))
==> (but that is my (dans) opinion)

==> (but that is my (dans) opinion)```

### Programming with Lists

• Here are some recursive programs with nested lists
```: (define (are-you-a-list l)
(if (null? l) '()
(cons (list? (car l))
(are-you-a-list (cdr l)))))

: (are-you-a-list '(a (b c) () ((d))) )
==> (#f #t #t #t)```
• Note what happens when I change cons to list:
```: (define (are-you-a-list-broken l)
(if (null? l) '()
(list (list? (car l))
(are-you-a-list-broken (cdr l)))))

: (are-you-a-list-broken '(a (b c) () ((d))) )
==> (#f (#t (#t (#t ()))))```

• They're really a simplification of lists! (and soylent green is made of people!)
• We "watered-down" lists and added constructs from the logo (butfirst, etc) programming language when we first taught you sentences.

### Higher-Order Functions

• There are three primary higher-order functions similar to the sentence HOFs which operate on the top-level elements of lists:
• map (similar to every)
• filter (similar to keep)
• reduce (similar to accumulate)
• Examples:
```: (define (are-you-a-list-hof l)
(map list? l))

: (are-you-a-list-hof '(a (b c) () ((d))) )
==> (#f #t #t #t)```
• We couldn't have done this with sentences for two reasons:
• Sentences can't have nested lists
• The returned list cannot be a sentence because it has booleans in it.
• Filter all the lists and non-lists.
```: (filter list? '(a (b c) () ((d))) )
==> ((b c) () ((d)))

: (filter word? '(a (b c) () ((d))) )
==> (a)```
• Add a layer of inner parens, and then strip them!
```: (map list '(a b c d))
==> ((a) (b) (c) (d))

: (reduce append '((a) (b) (c) (d)) )
==> (a b c d)```

### Other Primitives for Lists: length, null?, list?, list-ref,equal?, member

#### length

• Lists also have length which we can query (much like the count of a sentence)
• (length list)
• returns the number of top-level elements in list (ala count)
```: (length '(1 2 3 4) )
==> 4

: (length '(a (b c) () ((d))) )
==> 4

: (length '())
==> 0```

#### null?

• When recursing, one often has to test for the null list using the predicate null?
• (null? list)
• returns #t iff list is null, otherwise #f. (ala empty? for sentences)
```: (null? '(1 2 3 4) )
==> #f

: (null? '() )
==> #t```

#### list?

• When you've been given something and are wondering whether it is a list...
• returns #t iff list is a list, otherwise #f. (ala sentence? for sentences)
```: (list? '(1 2 3 4) )
==> #t

: (list? '() )
==> #t

: (list? 'cs3 )
==> #f```

#### list-ref

• list-ref is like item (for sentences)
• (list-ref list position)
• returns the 0-origin (i.e., starting from 0) element from list specified by position.
```: (list-ref '(a b c d) 1)
==> b

: (list-ref '(a b c d) 5)
*** ERROR -- PAIR expected
(list-ref '(a b c d) 5)

: (list-ref '(a (b c) () ((d))) 3)
==> ((d))

: (list-ref '() 0)
*** ERROR -- PAIR expected
(list-ref '(a b c d) 5)```

#### equal?

• equal? works for lists also, and
• (equal? list1 list2)
• returns #t if two lists have the same printed representation.
```: (equal? '(a (b c) () ((d))) '(a (b c) () ((d))) )
==> #t```

#### member

• member is like member? (for sentences), except it's a semi-predicate
• (member element list)
• seaches through the top-level elements of list, and when it finds element, returns the part of list starting with element. If it don't find it, it returns #f.
```: (member '(b c) '(a (b c) () ((d))) )
==> ((b c) () ((d)))

: (member 'a-new-word '(a (b c) () ((d))) )
==> #f```

### Example (hard) problem : deep-add-1

• Write deep-add-1, which adds 1 to every number in a complex list of numbers but keeps the structure
• Requires: every element in the list be a number (i.e., don't worry about error checking for this)
```: (deep-add-1 '(1 (2 3) () ((4))) )
==> (2 (3 4) () ((5)))

```

## Summary

• Sentences are really made of lists
• Lists are a very powerful way of making a collection of anything!
• Unlike sentences, they can contain booleans, procedures, other lists, other sentences, and even a mixed bag of all of these!

## In Lab this week you'll see...

• CAL, CAL and more CAL

## In Life this week you'll see...

• The NCAA march madness continues. Too bad our women's team had to face UConn so early! :(
• Maybe our Bull market will continue and the Dow will crest 8?
• Celebration by our women's swimming team – we won the NCAA championship!