## LispKit List

Lists are heterogeneous data structures constructed out of *pairs* and an *empty list* object.

A *pair* consists of two fields called *car* and *cdr* (for historical reasons). Pairs are created by the procedure `cons`

. The *car* and *cdr* fields are accessed by the procedures `car`

and `cdr`

. As opposed to most other Scheme implementations, lists are immutable in LispKit. Thus, it is not possible to set the car and cdr fields of an already existing pair.

Pairs are used primarily to represent lists. A list is defined recursively as either the empty list or a pair whose cdr is a list. More precisely, the set of lists is defined as the smallest set *X* such that

- The empty list is in
*X* - If
*list*is in*X*, then any pair whose cdr field contains*list*is also in*X*.

The objects in the car fields of successive pairs of a list are the *elements* of the list. For example, a two-element list is a pair whose car is the first element and whose cdr is a pair whose car is the second element and whose cdr is the empty list. The *length* of a list is the number of elements, which is the same as the number of pairs.

The empty list is a special object of its own type. It is not a pair, it has no elements, and its length is zero.

The most general notation (external representation) for Scheme pairs is the "dotted" notation `(c1 . c2)`

where `c1`

is the value of the car field and `c2`

is the value of the cdr field. For example `(4 . 5)`

is a pair whose car is `4`

and whose cdr is `5`

. Note that `(4 . 5)`

is the external representation of a pair, not an expression that evaluates to a pair.

A more streamlined notation can be used for lists: the elements of the list are simply enclosed in parentheses and separated by spaces. The empty list is written `()`

. For example,

```
(a b c d e)
```

and

```
(a . (b . (c . (d . (e . ())))))
```

are equivalent notations for a list of symbols.

A chain of pairs not ending in the empty list is called an *improper list*. Note that an improper list is not a list. The list and dotted notations can be combined to represent improper lists:

```
(a b c . d)
```

is equivalent to

```
(a . (b . (c . d)))
```

### Basic constructors and predicates

**(cons x y)** [procedure]

Returns a pair whose car is *x* and whose cdr is *y*.

**(car xs)** [procedure]

Returns the contents of the car field of pair *xs*. Note that it is an error to take the car of the empty list.

**(cdr xs)** [procedure]

Returns the contents of the cdr field of pair *xs*. Note that it is an error to take the cdr of the empty list.

**(caar xs)** [procedure]

**(cadr**

*xs*)**(cdar**

*xs*)**(cddr**

*xs*)These procedures are compositions of `car`

and `cdr`

as follows:

```
(define (caar x) (car (car x)))
(define (cadr x) (car (cdr x)))
(define (cdar x) (cdr (car x)))
(define (cddr x) (cdr (cdr x)))
```

**(caaar xs)** [procedure]

**(caadr**

*xs*)...

**(cdddr**

*xs*)These twenty-four procedures are further compositions of `car`

and `cdr`

on the same principles. For example, `caddr`

could be defined by `(define caddr (lambda (x) (car (cdr (cdr x)))))`

. Arbitrary compositions up to four deep are provided.

**(make-list k)** [procedure]

**(make-list**

*k fill*)Returns a list of *k* elements. If argument *fill* is given, then each element is set to *fill*. Otherwise the content of each element is the empty list.

**(list x ...)** [procedure]

Returns a list of its arguments, i.e. (*x ...*).

```
(list ’a (+ 3 4) ’c) ⇒ (a 7 c)
(list) ⇒ ()
```

**(length xs)** [procedure]

Returns the length of list *xs*.

```
(length ’(a b c)) ⇒ 3
(length ’(a (b) (c d e))) ⇒ 3
(length ’()) ⇒ 0
```

### Predicates

**(pair? obj)** [procedure]

Returns `#t`

if *obj* is a pair, `#f`

otherwise.

**(null? obj)** [procedure]

Returns `#t`

if *obj* is an empty list, `#f`

otherwise.

**(list? obj)** [procedure]

Returns `#t`

if *obj* is a proper list, `#f`

otherwise. A chain of pairs ending in the empty list is called a *proper list*.

**(every? pred xs ...)** [procedure]

Applies the predicate *pred* across the lists *xs ...*, returning `#t`

if the predicate returns `#t`

on every application. If there are *n* list arguments *xs1 ... xsn*, then *pred* must be a procedure taking *n* arguments and returning a single value, interpreted as a boolean. If an application of *pred* returns *#f*, then `every?`

returns `#f`

immediately without applying *pred* further anymore.

**(any? pred xs ...)** [procedure]

Applies the predicate *pred* across the lists *xs ...*, returning `#t`

if the predicate returns `#t`

for at least one application. If there are *n* list arguments *xs1 ... xsn*, then *pred* must be a procedure taking *n* arguments and returning a single value, interpreted as a boolean. If an application of *pred* returns *#t*, then `any?`

returns `#t`

immediately without applying *pred* further anymore.

### Composing and transforming lists

**(append xs ...)** [procedure]

Returns a list consisting of the elements of the first list *xs*
followed by the elements of the other lists. If there are no arguments, the empty list is returned. If there is exactly one argument, it is returned. The last argument, if there is one, can be of any type. An improper list results if the last argument is not a proper list.

```
(append ’(x) ’(y)) ⇒ (x y)
(append ’(a) ’(b c d)) ⇒ (a b c d)
(append ’(a (b)) ’((c))) ⇒ (a (b) (c))
(append ’(a b) ’(c . d)) ⇒ (a b c . d)
(append ’() ’a) ⇒ a
```

**(concatenate xss)** [procedure]

This procedure appends the elements of the list of lists *xss*. That is, `concatenate`

returns (`apply`

`append`

*xss*).

**(reverse xs)** [procedure]

Procedure `reverse`

returns a list consisting of the elements of list *xs* in reverse order.

```
(reverse '(a b c)) ⇒ (c b a)
(reverse '(a (b c) d (e (f)))) ⇒ ((e (f)) d (b c) a)
```

**(filter pred xs)** [procedure]

**(remove pred xs)** [procedure]

**(partition pred xs)** [procedure]

**(map f xs ...)** [procedure]

**(for-each f xs ...)** [procedure]

**(fold-left f z xs ...)** [procedure]

**(fold-right f z xs ...)** [procedure]

**(sort less xs)** [procedure]

**(merge less xs ys)** [procedure]

**(tabulate count proc)** [procedure]

**(iota count)** [procedure]

**(iota**

*count start*)**(iota**

*count start step*)### Finding and extracting elements

**(list-tail xs k)** [procedure]

**(list-ref xs k)** [procedure]

**(memq obj xs)** [procedure]

**(memv**

*obj xs*)**(member**

*obj xs*)**(member**

*obj xs compare*)These procedures return the first sublist of *xs* whose car is *obj*, where the sublists of *xs* are the non-empty lists returned by (`list-tail`

*xs k*) for *k* less than the length of *xs*. If *obj* does not occur in *xs*, then `#f`

is returned. The `memq`

procedure uses `eq?`

to compare *obj* with the elements of *xs*, while `memv`

uses `eqv?`

and `member`

uses *compare*, if given, and `equal?`

otherwise.

**(delq obj xs)** [procedure]

**(delv**

*obj xs*)**(delete**

*obj xs*)**(delete**

*obj xs compare*)**(assq obj alist)** [procedure]

**(assv**

*obj alist*)**(assoc**

*obj alist*)**(assoc**

*obj alist compare*)*alist* must be an association list, i.e. a list of key/value pairs. This family of procedures finds the first pair in *alist* whose car field is *obj*, and returns that pair. If no pair in *alist* has *obj* as its car, then `#f`

is returned. The `assq`

procedure uses `eq?`

to compare *obj* with the car fields of the pairs in *alist*, while `assv`

uses `eqv?`

and `assoc`

uses *compare* if given, and `equal?`

otherwise.

```
(define e '((a 1) (b 2) (c 3)))
(assq 'a e) ⇒ (a 1)
(assq 'b e) ⇒ (b 2)
(assq 'd e) ⇒ #f
(assq (list 'a) '(((a)) ((b)) ((c)))) ⇒ #f
(assoc (list 'a) '(((a)) ((b)) ((c)))) ⇒ ((a))
(assq 5 '((2 3) (5 7) (11 13))) ⇒ unspecified
(assv 5 '((2 3) (5 7) (11 13))) ⇒ (5 7)
```

**(alist-delq obj alist)** [procedure]

**(alist-delv**

*obj alist*)**(alist-delete**

*obj alist*)**(alist-delete**

*obj alist compare*)**(key xs)** [procedure]

**(key**

*xs default*)**(value xs)** [procedure]

**(value**

*xs default*)