### Page 162

#### nil!

Exercise for the reader: what's the difference between Graham's `nil!` and the following:

```(defun set-nil (x)
(setf x nil))```

### Page 163

#### Macro functions

The comment at the top of the page about macros being functions is confusing. Macros are not functions, so you can't pass a macro to `apply`, `mapcar`, etc.

However, macros work by calling macro expanders to expand the macro call into Lisp code. Macro expanders are functions. You can get the macro expander for a macro using `macro-function`.

### Page 165

#### rotatef

Why is the macro that swaps two variables called `rotatef`? Well, the `f` part is by analogy to `setf`. `rotatef` operates on "places" just like `setf` does. The `rotate` part is because `rotatef` can handle any number of places, not just two. See the glossary in Graham for details.

#### Quicksort

If you do the `list-of` macro exercise, then you can define `quicksort` on a list (not a vector) like this:

```(defun quicksort (l)
(cond ((null l) nil)
(t (let ((p (car l))
(r (cdr l)))
(append (quicksort (list-of x (x :in r) (< x p)))
(list p)
(quicksort (list-of x (x :in r) (>= x p))))))))```

This is pretty inefficient (it conses a lot), but it does capture the essence of the algorithm nicely: choose a pivot p and split the list into those items less than p and greater than p.

### Page 169

Graham's `append1f` example is not portable. On this page and in the glossary, he correctly says that `define-modify-macro` requires a function name. Why he then used a `lambda` I can't say.

### Page 172

#### avg

This is a cute example of compile-time optimization but it's also an example of an evil macro.

Faculty: Chris Riesbeck
Time: Monday, Wednesday, Friday: 11am - 11:50am
Location: Tech LR5