diff --git a/1-04-0-lists.md b/1-04-0-lists.md
index b3d556c6bf9924c11126ead85f0702b2d0d851c5..68aab5a072f2f9d156a0d41024769a04ddbf75b8 100644
--- a/1-04-0-lists.md
+++ b/1-04-0-lists.md
@@ -13,700 +13,25 @@ This is also the key to Lisp's homoiconicity---the same syntax is used to repres
 
 But Lists are also a proper type in Common Lisp, that descends from sequences.  We have already seen some sequence operations on other data types, like Strings, and will explore them further.  However, in this chapter, we will focus on Lists as a proper data type and Consing operations on these Lists.
 
-* Consing and Cons-Cells
-* The LIST Function
-* CAR and CDR
-* FIRST, REST, and LAST
-* PUSH and POP
-* List Position
-* APPEND
-* Quoting
-* Circular Lists
-* Circular Trees
-
-### Exercise 1.4.1
-
-**Cons-Cells**
-
-Cons-Cells are the smallest compound data structure in Lisp. A Cons-Cell is effectively a pair of pointers. You can tell if what you're looking at is a Cons-Cell by using the predicate `consp`.
-
-```lisp
-* (consp 5)
-NIL
-
-* (consp "a")
-NIL
-
-* (consp 'a)
-NIL
-
-* (consp (cons 'a 'b))
-T
-```
-
-### Exercise 1.4.2
-
-**Consing**
-
-One way to create a Cons-Cell is using the `cons` function.
-
-```lisp
-* (cons 'a 'b)
-(A . B)
-```
-
-They can hold any `type` of data, not just symbols.
-
-```lisp
-* (cons 1 2)
-(1 . 2)
-
-* (cons "one" "two")
-("one" . "two")
-```
-
-### Exercise 1.4.3
-
-**Dot-Notation**
-
-You can see that when we cons two atoms together, we get back a Dotted Pair. This is a `read`able representation of Cons-Cells. That is, you can use it directly, rather than calling `cons`.
-
-```lisp
-* (cons 'a 'b)
-(A . B)
-
-* '(a . b)
-(A . B)
-```
-
-These two representations are equivalent.
-
-```lisp
-* (equal (cons 'a 'b) '(a . b))
-T
-```
-
-### Exercise 1.4.4
-
-**More Consing**
-
-Cons-Cells need not contain homogenous data.
-
-```lisp
-* (cons 'a 2)
-(A . 2)
-
-* (cons 1 "two")
-(1 . "two")
-
-* (cons "a" 'b)
-("a" . B)
-```
-
-### Exercise 1.4.5
-
-**CAR and CDR**
-
-Using Cons-Cells as building blocks would be kind of pointless if we couldn't get their components back out. To get the value of the first slot in a Cons-Cell, we use the `car` function.
-
-```lisp
-* (cons 'a 'b)
-(A . B)
-
-* (car (cons 'a 'b))
-A
-```
-
-Similarly, we can get the value from the second slot in a Cons-Cell using `cdr`.
-
-```lisp
-* (cons 1 2)
-(1 . 2)
-
-* (cdr (cons 1 2))
-2
-```
-
-### Exercise 1.4.6
-
-**More CAR and CDR**
-
-`cons`, `car` and `cdr` are purely functional. Which means they never mutate their arguments.
-
-```lisp
-* (defvar *a* (cons 1 2))
-*A*
-
-* *a*
-(1 . 2)
-
-* (cdr *a*)
-2
-
-* *a*
-(1 . 2)
-
-* (cons 3 (cdr *a*))
-(3 . 2)
-
-* *a*
-(1 . 2)
-```
-
-It is an error to use `car` and `cdr` on something other than a Cons-Cell.
-
-```lisp
-* (car 1)
-; Evaluation aborted on #<TYPE-ERROR expected-type: LIST datum: 1>
-
-* (cdr 'a)
-; Evaluation aborted on #<TYPE-ERROR expected-type: LIST datum: A>.
-```
-
-This includes other compound values such as strings and vectors
-
-```lisp
-* (car "a")
-; Evaluation aborted on #<TYPE-ERROR expected-type: LIST datum: "a">.
-
-* (cdr #(1 2))
-; Evaluation aborted on #<TYPE-ERROR expected-type: LIST datum: #<(SIMPLE-VECTOR 2) {1007D4C76F}>>.
-```
-
-but not the empty list, also represented as `NIL`
-
-```lisp
-* (car nil)
-NIL
-
-* (cdr nil)
-NIL
-
-* (car ())
-NIL
-
-* (cdr ())
-NIL
-```
-
-### Exercise 1.4.7
-
-**Lists**
-
-A list is either the empty list, or a chain of Cons-Cells ending with the empty list.
-
-```lisp
-* (listp nil)
-T
-
-* (listp (cons 5 nil))
-T
-```
-If you cons something onto the empty list, you get the list of that thing.
-
-```lisp
-* (cons 5 nil)
-(5)
-```
-We can exploit the Cons-Cells' ability to contain heterogenous data in order to represent linked lists or trees.
-
-```lisp
-* (cons 3 (cons 2 (cons 1 nil)))
-(3 2 1)
-```
-
-### Exercise 1.4.8
-
-**More Lists**
-
-Another way to create lists is using the `list` function.
-
-```lisp
-* (list 3 2 1)
-(3 2 1)
-```
-
-The expression `(list a b ...)` is effectively shorthand for the expression `(cons a (cons b ...))`, with the final value being `cons`ed onto `NIL`.
-
-```lisp
-* (list 1 2 3)
-(1 2 3)
-
-* (cons 1 (cons 2 (cons 3 nil)))
-(1 2 3)
-
-* (equal (list 1 2 3) (cons 1 (cons 2 (cons 3 nil))))
-T
-```
-
-As with `cons`, it's possible to build up trees, rather than merely lists, using `list`.
-
-```lisp
-* (list 1 (list 2 3) (list 4 (list (list 5) 6 7 8)))
-(1 (2 3) (4 ((5) 6 7 8)))
-```
-
-### Exercise 1.4.9
-
-**Even More CAR and CDR**
-
-Because `car` and `cdr` are purely functional, and return their target value, it's possible to chain them in order to look into nested structures.
-
-```lisp
-* (cons (cons 1 2) 3)
-((1 . 2) . 3)
-
-* (car (car (cons (cons 1 2) 3)))
-1
-```
-
-This also applies to deeply nested lists.
-
-```lisp
-* (defparameter *tree* (list 1 (list 2 3) (list 4 (list (list 5) 6 7 8))))
-*tree*
-
-* *tree*
-(1 (2 3) (4 ((5) 6 7 8)))
-
-* (car (cdr (car (cdr *tree*))))
-3
-```
-
-This is common enough that Lisp supports shorthand for such tree selections.
-
-```lisp
-* (car *tree*)
-1
-
-* (cadr *tree*)
-
-(2 3)
-
-* (cadadr *tree*)
-3
-
-* (cddr *tree*)
-((4 ((5) 6 7 8)))
-
-* (cdddr *tree*)
-NIL
-```
-
-They're actual functions though. Not a reader syntax based on the number of `a`s and `d` s between the `c` and `r`. So, for instance:
-
-```lisp
-* (caddadddaaar *tree*)
-   The function COMMON-LISP-USER::CADDADDDAAAR is undefined.
-      [Condition of type UNDEFINED-FUNCTION]
-```
-
-### Exercise 1.4.10
-
-**Push and Pop**
-
-We mentioned before that `cons`, `car`, `cdr` and friends are purely functional. But, sometimes, you want to destructively modify a list you've defined. For instance, in order to implement a mutable stack. In order to destructively `cons` elements onto a list, use `push`.
-
-```lisp
-* (defvar *stack* nil)
-*stack*
-
-* (push 1 *stack*)
-(1)
-
-* *stack*
-(1)
-
-* (push 2 *stack*)
-(2 1)
-
-* (push 3 *stack*)
-(3 2 1)
-
-* *stack*
-(3 2 1)
-```
-
-### Exercise 1.4.11
-
-**Pop**
-
-The other half of the a stack involves destructively removing the first element from it. This can be done with `pop`.
-
-```lisp
-* *stack*
-(3 2 1)
-
-* (pop *stack*)
-3
-
-* *stack*
-(2 1)
-
-* (pop *stack*)
-2
-
-* (pop *stack*)
-1
-
-* *stack*
-NIL
-```
-
-Calling `pop` on an empty list has no effect.
-
-```lisp
-* *stack*
-NIL
-
-* (pop *stack*)
-NIL
-
-* *stack*
-NIL
-```
-
-### Exercise 1.4.12
-
-**More Push and Pop**
-
-Like `cons`, `push` isn't limited to the existing type of its target.
-
-```lisp
-* *stack*
-NIL
-
-* (push 1 *stack*)
-(1)
-
-* (push "b" *stack*)
-("b" 1)
-
-* (push 'c *stack*)
-(c "b" 1)
-
-* (push (list 4 5) *stack*)
-((4 5) C "a" 1)
-
-* *stack*
-((4 5) C "a" 1)
-```
-
-### Exercise 1.4.13
-
-**First, Rest, and Last**
-
-In addition to `car` and `cdr`, it's also possible to manipulate Cons-Cells using the `first` and `rest` functions. They're just different names for the same functions. `first` is the same as `car`
-
-```lisp
-* (cons 'a 'b)
-(A . B)
-
-* (car (cons 'a 'b))
-A
-
-* (first (cons 'a 'b))
-A
-```
-
-and `rest` is the same as `cdr`
-
-```lisp
-* (cons 1 2)
-(1 . 2)
-
-* (cdr (cons 1 2))
-2
-
-* (rest (cons 1 2))
-2
-```
-
-A third function, `last`, lets you get at the last Cons-Cell in a particular series.
-
-```lisp
-* (last (cons 1 (cons 2 (cons 3 nil))))
-(3)
-
-* (last (cons 1 2))
-(1 . 2)
-
-* (last (list 3 4 5))
-(5)
-```
-
-### Exercise 1.4.14
-
-**List Position**
-
-When dealing with linked lists, if you want to get at a particular element somewhere in the middle, you could either chain some `car`s and `cdr`s.
-
-```lisp
-* (car (cdr (cdr (cdr (list 0 1 2 3 4 5)))))
-3
-
-* (cadddr (list 0 1 2 3 4 5))
-3
-```
-
-or you could use the `nth` function.
-
-```lisp
-* (nth 3 (list 0 1 2 3 4 5))
-3
-
-* (nth 4 (list 0 1 2 3 4 5))
-4
-
-* (nth 5 (list 5 4 3 2 1 0))
-0
-```
-
-This isn't any more efficient (in the run-time sense) than `cdr` traversal, but is shorter to write if you need to access some deeper list element in a flat list.
-
-### Exercise 1.4.15
-
-**Appending**
-
-Putting lists together is the job of the `append` function.
-
-```lisp
-* (append (list 1 2 3) (list 4 5 6))
-(1 2 3 4 5 6)
-
-* (append (list 6 5 4 3) (list 2 1))
-(6 5 4 3 2 1)
-```
-
-`append` is an example of a function that takes a `&rest` argument. Meaning you can pass it any number of lists...
-
-```lisp
-* (append (list 'a 'b 'c 'd) (list 'e 'f) (list 'g))
-(A B C D E F G)
-
-* (append (list 1) (list 2) (list 3) (list 4))
-(1 2 3 4)
-```
-
-...though passing it one list is pointless.
-
-```lisp
-* (append (list 1 2 3))
-(1 2 3)
-
-* (list 1 2 3)
-(1 2 3)
-```
-### Exercise 1.4.16
-
-**More Appending**
-
-Like `car`, `cdr`, `first`, `rest`, `last` and `nth`, `append` is functional. It will return a new list rather than mutating any of its arguments.
-
-```lisp
-* (defvar *lst* (list 1 2 3 4 5))
-*lst*
-
-* *lst*
-(1 2 3 4 5)
-
-* (append *lst* (list 6 7 8))
-(1 2 3 4 5 6 7 8)
-
-* *lst*
-(1 2 3 4 5)
-
-* (append (list -3 -2 -1 0) *lst*)
-(-3 -2 -1 0 1 2 3 4 5)
-
-* *lst*
-(1 2 3 4 5)
-
-* (append (list 0) *lst* (list 6))
-(0 1 2 3 4 5 6)
-
-* *lst*
-(1 2 3 4 5)
-```
-
-This means both that you may safely pass it any data you want appended without worrying about losing the original lists, and that if you want such behavior, you need to explicitly assign the result of `append` yourself.
-
-
-### Exercise 1.4.17
-
-**Circular Lists**
-
-The destructive equivalent of `append` is `nconc`. Using such side-effects, it's possible to create circular lists.
-
-```lisp
-* (defparameter *cycle* (list 'a 'b))
-*CYCLE*
-
-* (first *cycle*)
-A
-
-* (second *cycle*)
-B
-
-* (third *cycle*)
-NIL
-
-* (fourth *cycle*)
-NIL
-```
-
-Before we create an actual cycle, we need to tell the interpreter to print them (otherwise the request to print a circular list would never return; unlike Haskell, Common Lisp is not a lazy language by default).
-
-```lisp
-* (setf *print-circle* t)
-T
-
-* (nconc *cycle* *cycle*)
-#1=(A B . #1#)
-
-* (third *cycle*)
-A
-
-* (fourth *cycle*)
-B
-
-* (loop repeat 15 for elem in *cycle* collect elem)
-(A B A B A B A B A B A B A B A)
-```
-
-### Exercise 1.4.18
-
-**Circular Trees**
-
-The `nconc` procedure is fine when all you want is a simple cycle, but it's also possible to use direct mutation to create more elaborate structures.
-
-```lisp
-* (defparameter *knot* (list 1 2 3 4 (cons nil nil)))
-*KNOT*
-
-* (setf (car (nth 4 *knot*)) (cdr *knot*))
-#1=(1 2 3 4 (#1#))
-
-* (setf (cdr (nth 4 *knot*)) (cddr *knot*))
-#1=(3 4 ((1 2 . #1#) . #1#))
-```
-
-Now we've got a structure that branches back on itself twice.
-
-```lisp
-* (defun cycle-walk (count cycle &key (turn #'car))
-    (loop with place = cycle
-          repeat count for elem = (car place)
-          unless (consp elem) do (format t "~a " elem)
-          do (setf place (if (consp elem)
-			                 (funcall turn elem)
-			                 (cdr place)))))
-CYCLE-WALK
-
-* (cycle-walk 25 *knot* :turn #'car)
-1 2 3 4 2 3 4 2 3 4 2 3 4 2 3 4 2 3 4
-NIL
-
-* (cycle-walk 25 *knot* :turn #'cdr)
-1 2 3 4 3 4 3 4 3 4 3 4 3 4 3 4 3 4
-NIL
-
-* (let ((dir))
-    (defun switch (pair)
-      (setf dir (not dir))
-      (if dir
-	      (car pair)
-	      (cdr pair))))
-SWITCH
-
-* (cycle-walk 25 *knot* :turn #'switch)
-1 2 3 4 3 4 2 3 4 3 4 2 3 4 3 4 2 3 4
-NIL
-```
-
-Of course, it's possible to go further. Large, divergent "trees" that eventually cycle backwards from any number of branches at arbitrary depths. You'd build them the same way though; using some combination of `nconc`, `setf` along with `car`/`cdr` and friends.
-
-
-### Exercise 1.4.19
-
-**Quoting**
-
-Another way to construct tree structure is using the `quote` or `'`.
-
-```lisp
-* (quote (1 2 3))
-(1 2 3)
-
-* '(1 2 3)
-(1 2 3)
-
-* (list 1 2 3)
-(1 2 3)
-```
-
-The structures you create this way are equivalent.
-
-```lisp
-* (equal (quote (1 2 3)) '(1 2 3))
-T
-
-* (equal '(1 2 3) (list 1 2 3))
-T
-```
-
-The difference is that, while `list` essentially means "Return the list of these arguments", `quote`/`'` means "Return this argument without evaluating it".
-
-```lisp
-* (defparameter *test* 2)
-*test*
-
-* (list 1 *test* 3)
-(1 2 3)
-
-* '(1 *test* 3)
-(1 *test* 3)
-
-* (list (+ 3 4) (+ 5 6) (+ 7 8))
-(7 11 15)
-
-* '((+ 3 4) (+ 5 6) (+ 7 8))
-((+ 3 4) (+ 5 6) (+ 7 8))
-```
-
-### Exercise 1.4.20
-
-**More Quoting**
-
-Because `quote` supresses evaluation, you can use it to more easily build deeply nested structures.
-
-```lisp
-* (list 1 (list 2 3) (list 4 (list (list 5) 6 7 8)))
-(1 (2 3) (4 ((5) 6 7 8)))
-
-* '(1 (2 3) (4 ((5) 6 7 8)))
-(1 (2 3) (4 ((5) 6 7 8)))
-```
-
-Take care not to use quoted data for mutation though. While the structures produced may be the same, mutating a quoted structure is undefined by the Common Lisp language spec, and is thus entirely implementation dependant.
-
-```lisp
-* (defvar *listed* (list 3 2 1))
-*listed*
-
-* (defvar *quoted* '(3 2 1))
-*quoted*
-
-* (push 4 *listed*)
-(4 3 2 1)
-
-* *listed*
-(4 3 2 1)
-
-* (push 4 *quoted*)
-???
-
-* *quoted*
-???
-```
-
-The question marks aren't there so you can figure out what the results are supposed to be. They signify that what you get back in these situations depends on which implementation of Common Lisp you're using. They may do incompatible things, but because the spec leaves this situation undefined, none of them are actually wrong. So, you know ... careful.
+## Exercises
+
+* [Cons-Cells](./1-04-01-cons-cells.md)
+* [Consing](./1-04-02-consing.md)
+* [Dot-Notation](./1-04-03-dot-notation.md)
+* [More Consing](./1-04-04-more-consing.md)
+* [CAR and CDR](./1-04-05-car-and-cdr.md)
+* [More CAR and CDR](./1-04-06-more-car-and-cdr.md)
+* [Lists](./1-04-07-lists.md)
+* [More Lists](./1-04-08-more-lists.md)
+* [Even More CAR and CDR](./1-04-09-even-more-car-and-cdr.md)
+* [Stacks](./1-04-10-stacks.md)
+* [PUSH and POP](./1-04-11-push-and-pop.md)
+* [More PUSH and POP](./1-04-12-more-push-and-pop.md)
+* [FIRST, REST, and LAST](./1-04-13-first-rest-last.md)
+* [List Position](./1-04-14-list-position.md)
+* [Appending](./1-04-15-appending.md)
+* [More Appending](./1-04-16-more-appending.md)
+* [Circular Lists](./1-04-17-circular-lists.md)
+* [Circular Trees](./1-04-18-circular-trees.md)
+* [Quoting](./1-04-19-quoting.md)
+* [More Quoting](./1-04-20-more-quoting.md)
diff --git a/1-04-01-cons-cells.md b/1-04-01-cons-cells.md
new file mode 100644
index 0000000000000000000000000000000000000000..89e2d2d0d0748b58df16316cf92fc600bba82466
--- /dev/null
+++ b/1-04-01-cons-cells.md
@@ -0,0 +1,35 @@
+# Exercise 1.4.1
+
+## Cons-Cells
+
+Cons-Cells are the smallest compound data structure in Lisp. A Cons-Cell is effectively a pair of pointers. You can tell if what you're looking at is a Cons-Cell by using the predicate `consp`, and you can create a Cons-Cell using the function `cons`.
+
+### In the REPL
+
+```lisp
+(consp 5)
+
+(consp "a")
+
+(consp 'a)
+
+(consp (cons 'a 'b))
+```
+
+### Wnat You Should See
+
+Numbers, strings, and symbols are not Cons-Cells, so the `consp` predicate returns `nil`. You can create a Cons-Cell of two other objects with the `cons` function, which returns a fresh Cons-Cell every time it is called. This operation is called *consing*, and we will explore it further in the following exercises.
+
+```lisp
+* (consp 5)
+NIL
+
+* (consp "a")
+NIL
+
+* (consp 'a)
+NIL
+
+* (consp (cons 'a 'b))
+T
+```
diff --git a/1-04-02-consing.md b/1-04-02-consing.md
new file mode 100644
index 0000000000000000000000000000000000000000..d07a93f42d28ba8b6c983d7ab0ffd81abbf0d31b
--- /dev/null
+++ b/1-04-02-consing.md
@@ -0,0 +1,20 @@
+# Exercise 1.4.2
+
+## Consing
+
+One way to create a Cons-Cell is using the `cons` function.
+
+```lisp
+* (cons 'a 'b)
+(A . B)
+```
+
+They can hold any `type` of data, not just symbols.
+
+```lisp
+* (cons 1 2)
+(1 . 2)
+
+* (cons "one" "two")
+("one" . "two")
+```
diff --git a/1-04-03-dot-notation.md b/1-04-03-dot-notation.md
new file mode 100644
index 0000000000000000000000000000000000000000..1fbb6210623ed48517ce9dfcc4700d624f9b9749
--- /dev/null
+++ b/1-04-03-dot-notation.md
@@ -0,0 +1,20 @@
+# Exercise 1.4.3
+
+## Dot-Notation
+
+You can see that when we cons two atoms together, we get back a Dotted Pair. This is a `read`able representation of Cons-Cells. That is, you can use it directly, rather than calling `cons`.
+
+```lisp
+* (cons 'a 'b)
+(A . B)
+
+* '(a . b)
+(A . B)
+```
+
+These two representations are equivalent.
+
+```lisp
+* (equal (cons 'a 'b) '(a . b))
+T
+```
diff --git a/1-04-04-more-consing.md b/1-04-04-more-consing.md
new file mode 100644
index 0000000000000000000000000000000000000000..8c0831601090e61314d1bc79962707d1a5b69dc6
--- /dev/null
+++ b/1-04-04-more-consing.md
@@ -0,0 +1,16 @@
+# Exercise 1.4.4
+
+## More Consing
+
+Cons-Cells need not contain homogenous data.
+
+```lisp
+* (cons 'a 2)
+(A . 2)
+
+* (cons 1 "two")
+(1 . "two")
+
+* (cons "a" 'b)
+("a" . B)
+```
diff --git a/1-04-05-car-and-cdr.md b/1-04-05-car-and-cdr.md
new file mode 100644
index 0000000000000000000000000000000000000000..47047d5c93b822feeee0ec572af1fd73aecdf562
--- /dev/null
+++ b/1-04-05-car-and-cdr.md
@@ -0,0 +1,23 @@
+# Exercise 1.4.5
+
+## CAR and CDR
+
+Using Cons-Cells as building blocks would be kind of pointless if we couldn't get their components back out. To get the value of the first slot in a Cons-Cell, we use the `car` function.
+
+```lisp
+* (cons 'a 'b)
+(A . B)
+
+* (car (cons 'a 'b))
+A
+```
+
+Similarly, we can get the value from the second slot in a Cons-Cell using `cdr`.
+
+```lisp
+* (cons 1 2)
+(1 . 2)
+
+* (cdr (cons 1 2))
+2
+```
diff --git a/1-04-06-more-car-and-cdr.md b/1-04-06-more-car-and-cdr.md
new file mode 100644
index 0000000000000000000000000000000000000000..956742fcb3c41e445a0a16567d165469a7dd7e99
--- /dev/null
+++ b/1-04-06-more-car-and-cdr.md
@@ -0,0 +1,61 @@
+# Exercise 1.4.6
+
+## More CAR and CDR
+
+`cons`, `car` and `cdr` are purely functional. Which means they never mutate their arguments.
+
+```lisp
+* (defvar *a* (cons 1 2))
+*A*
+
+* *a*
+(1 . 2)
+
+* (cdr *a*)
+2
+
+* *a*
+(1 . 2)
+
+* (cons 3 (cdr *a*))
+(3 . 2)
+
+* *a*
+(1 . 2)
+```
+
+It is an error to use `car` and `cdr` on something other than a Cons-Cell.
+
+```lisp
+* (car 1)
+; Evaluation aborted on #<TYPE-ERROR expected-type: LIST datum: 1>
+
+* (cdr 'a)
+; Evaluation aborted on #<TYPE-ERROR expected-type: LIST datum: A>.
+```
+
+This includes other compound values such as strings and vectors
+
+```lisp
+* (car "a")
+; Evaluation aborted on #<TYPE-ERROR expected-type: LIST datum: "a">.
+
+* (cdr #(1 2))
+; Evaluation aborted on #<TYPE-ERROR expected-type: LIST datum: #<(SIMPLE-VECTOR 2) {1007D4C76F}>>.
+```
+
+but not the empty list, also represented as `NIL`
+
+```lisp
+* (car nil)
+NIL
+
+* (cdr nil)
+NIL
+
+* (car ())
+NIL
+
+* (cdr ())
+NIL
+```
diff --git a/1-04-07-lists.md b/1-04-07-lists.md
new file mode 100644
index 0000000000000000000000000000000000000000..29522fc2f80602a7014baa49d63fc5e9f88f2ddb
--- /dev/null
+++ b/1-04-07-lists.md
@@ -0,0 +1,25 @@
+# Exercise 1.4.7
+
+## Lists
+
+A list is either the empty list, or a chain of Cons-Cells ending with the empty list.
+
+```lisp
+* (listp nil)
+T
+
+* (listp (cons 5 nil))
+T
+```
+If you cons something onto the empty list, you get the list of that thing.
+
+```lisp
+* (cons 5 nil)
+(5)
+```
+We can exploit the Cons-Cells' ability to contain heterogenous data in order to represent linked lists or trees.
+
+```lisp
+* (cons 3 (cons 2 (cons 1 nil)))
+(3 2 1)
+```
diff --git a/1-04-08-more-lists.md b/1-04-08-more-lists.md
new file mode 100644
index 0000000000000000000000000000000000000000..ba80e1fad128cad1f1084a6671a6e036dc206311
--- /dev/null
+++ b/1-04-08-more-lists.md
@@ -0,0 +1,30 @@
+# Exercise 1.4.8
+
+## More Lists
+
+Another way to create lists is using the `list` function.
+
+```lisp
+* (list 3 2 1)
+(3 2 1)
+```
+
+The expression `(list a b ...)` is effectively shorthand for the expression `(cons a (cons b ...))`, with the final value being `cons`ed onto `NIL`.
+
+```lisp
+* (list 1 2 3)
+(1 2 3)
+
+* (cons 1 (cons 2 (cons 3 nil)))
+(1 2 3)
+
+* (equal (list 1 2 3) (cons 1 (cons 2 (cons 3 nil))))
+T
+```
+
+As with `cons`, it's possible to build up trees, rather than merely lists, using `list`.
+
+```lisp
+* (list 1 (list 2 3) (list 4 (list (list 5) 6 7 8)))
+(1 (2 3) (4 ((5) 6 7 8)))
+```
diff --git a/1-04-09-even-more-car-and-cdr.md b/1-04-09-even-more-car-and-cdr.md
new file mode 100644
index 0000000000000000000000000000000000000000..9a299e9346b2ae7426fb6d43a4587d118e42ce2b
--- /dev/null
+++ b/1-04-09-even-more-car-and-cdr.md
@@ -0,0 +1,54 @@
+# Exercise 1.4.9
+
+## Even More CAR and CDR
+
+Because `car` and `cdr` are purely functional, and return their target value, it's possible to chain them in order to look into nested structures.
+
+```lisp
+* (cons (cons 1 2) 3)
+((1 . 2) . 3)
+
+* (car (car (cons (cons 1 2) 3)))
+1
+```
+
+This also applies to deeply nested lists.
+
+```lisp
+* (defparameter *tree* (list 1 (list 2 3) (list 4 (list (list 5) 6 7 8))))
+*tree*
+
+* *tree*
+(1 (2 3) (4 ((5) 6 7 8)))
+
+* (car (cdr (car (cdr *tree*))))
+3
+```
+
+This is common enough that Lisp supports shorthand for such tree selections.
+
+```lisp
+* (car *tree*)
+1
+
+* (cadr *tree*)
+
+(2 3)
+
+* (cadadr *tree*)
+3
+
+* (cddr *tree*)
+((4 ((5) 6 7 8)))
+
+* (cdddr *tree*)
+NIL
+```
+
+They're actual functions though. Not a reader syntax based on the number of `a`s and `d` s between the `c` and `r`. So, for instance:
+
+```lisp
+* (caddadddaaar *tree*)
+   The function COMMON-LISP-USER::CADDADDDAAAR is undefined.
+      [Condition of type UNDEFINED-FUNCTION]
+```
diff --git a/1-04-10-stacks.md b/1-04-10-stacks.md
new file mode 100644
index 0000000000000000000000000000000000000000..e3caf2f4e7083b5ead282efa619ce76a3ff75bb0
--- /dev/null
+++ b/1-04-10-stacks.md
@@ -0,0 +1,25 @@
+# Exercise 1.4.10
+
+## Stacks
+
+We mentioned before that `cons`, `car`, `cdr` and friends are purely functional. But, sometimes, you want to destructively modify a list you've defined. For instance, in order to implement a mutable stack. In order to destructively `cons` elements onto a list, use `push`.
+
+```lisp
+* (defvar *stack* nil)
+*stack*
+
+* (push 1 *stack*)
+(1)
+
+* *stack*
+(1)
+
+* (push 2 *stack*)
+(2 1)
+
+* (push 3 *stack*)
+(3 2 1)
+
+* *stack*
+(3 2 1)
+```
diff --git a/1-04-11-push-and-pop.md b/1-04-11-push-and-pop.md
new file mode 100644
index 0000000000000000000000000000000000000000..9e10e7685392f7e0cfbfacc55fb0e47e1d2592ad
--- /dev/null
+++ b/1-04-11-push-and-pop.md
@@ -0,0 +1,38 @@
+# Exercise 1.4.11
+
+## PUSH and POP
+
+The other half of the a stack involves destructively removing the first element from it. This can be done with `pop`.
+
+```lisp
+* *stack*
+(3 2 1)
+
+* (pop *stack*)
+3
+
+* *stack*
+(2 1)
+
+* (pop *stack*)
+2
+
+* (pop *stack*)
+1
+
+* *stack*
+NIL
+```
+
+Calling `pop` on an empty list has no effect.
+
+```lisp
+* *stack*
+NIL
+
+* (pop *stack*)
+NIL
+
+* *stack*
+NIL
+```
diff --git a/1-04-12-more-push-and-pop.md b/1-04-12-more-push-and-pop.md
new file mode 100644
index 0000000000000000000000000000000000000000..ee37aa50a658887cd7db7413de84e369427148b8
--- /dev/null
+++ b/1-04-12-more-push-and-pop.md
@@ -0,0 +1,25 @@
+# Exercise 1.4.12
+
+## More PUSH and POP
+
+Like `cons`, `push` isn't limited to the existing type of its target.
+
+```lisp
+* *stack*
+NIL
+
+* (push 1 *stack*)
+(1)
+
+* (push "b" *stack*)
+("b" 1)
+
+* (push 'c *stack*)
+(c "b" 1)
+
+* (push (list 4 5) *stack*)
+((4 5) C "a" 1)
+
+* *stack*
+((4 5) C "a" 1)
+```
diff --git a/1-04-13-first-rest-last.md b/1-04-13-first-rest-last.md
new file mode 100644
index 0000000000000000000000000000000000000000..b574e47e2a90ae34d18e13e395433040722ebd83
--- /dev/null
+++ b/1-04-13-first-rest-last.md
@@ -0,0 +1,42 @@
+# Exercise 1.4.13
+
+## FIRST, REST, and LAST
+
+In addition to `car` and `cdr`, it's also possible to manipulate Cons-Cells using the `first` and `rest` functions. They're just different names for the same functions. `first` is the same as `car`
+
+```lisp
+* (cons 'a 'b)
+(A . B)
+
+* (car (cons 'a 'b))
+A
+
+* (first (cons 'a 'b))
+A
+```
+
+and `rest` is the same as `cdr`
+
+```lisp
+* (cons 1 2)
+(1 . 2)
+
+* (cdr (cons 1 2))
+2
+
+* (rest (cons 1 2))
+2
+```
+
+A third function, `last`, lets you get at the last Cons-Cell in a particular series.
+
+```lisp
+* (last (cons 1 (cons 2 (cons 3 nil))))
+(3)
+
+* (last (cons 1 2))
+(1 . 2)
+
+* (last (list 3 4 5))
+(5)
+```
diff --git a/1-04-14-list-position.md b/1-04-14-list-position.md
new file mode 100644
index 0000000000000000000000000000000000000000..5e39ddd60753e2a792c8a0d663220afc3bea8d62
--- /dev/null
+++ b/1-04-14-list-position.md
@@ -0,0 +1,28 @@
+# Exercise 1.4.14
+
+## List Position
+
+When dealing with linked lists, if you want to get at a particular element somewhere in the middle, you could either chain some `car`s and `cdr`s.
+
+```lisp
+* (car (cdr (cdr (cdr (list 0 1 2 3 4 5)))))
+3
+
+* (cadddr (list 0 1 2 3 4 5))
+3
+```
+
+or you could use the `nth` function.
+
+```lisp
+* (nth 3 (list 0 1 2 3 4 5))
+3
+
+* (nth 4 (list 0 1 2 3 4 5))
+4
+
+* (nth 5 (list 5 4 3 2 1 0))
+0
+```
+
+This isn't any more efficient (in the run-time sense) than `cdr` traversal, but is shorter to write if you need to access some deeper list element in a flat list.
diff --git a/1-04-15-appending.md b/1-04-15-appending.md
new file mode 100644
index 0000000000000000000000000000000000000000..825d470d46b86730de7a5ec7dec1b0becae60867
--- /dev/null
+++ b/1-04-15-appending.md
@@ -0,0 +1,33 @@
+# Exercise 1.4.15
+
+## Appending
+
+Putting lists together is the job of the `append` function.
+
+```lisp
+* (append (list 1 2 3) (list 4 5 6))
+(1 2 3 4 5 6)
+
+* (append (list 6 5 4 3) (list 2 1))
+(6 5 4 3 2 1)
+```
+
+`append` is an example of a function that takes a `&rest` argument. Meaning you can pass it any number of lists...
+
+```lisp
+* (append (list 'a 'b 'c 'd) (list 'e 'f) (list 'g))
+(A B C D E F G)
+
+* (append (list 1) (list 2) (list 3) (list 4))
+(1 2 3 4)
+```
+
+...though passing it one list is pointless.
+
+```lisp
+* (append (list 1 2 3))
+(1 2 3)
+
+* (list 1 2 3)
+(1 2 3)
+```
diff --git a/1-04-16-more-appending.md b/1-04-16-more-appending.md
new file mode 100644
index 0000000000000000000000000000000000000000..d557eb3ae5ea3eb086aedbfa4e59840dbfac34d4
--- /dev/null
+++ b/1-04-16-more-appending.md
@@ -0,0 +1,33 @@
+# Exercise 1.4.16
+
+## More Appending
+
+Like `car`, `cdr`, `first`, `rest`, `last` and `nth`, `append` is functional. It will return a new list rather than mutating any of its arguments.
+
+```lisp
+* (defvar *lst* (list 1 2 3 4 5))
+*lst*
+
+* *lst*
+(1 2 3 4 5)
+
+* (append *lst* (list 6 7 8))
+(1 2 3 4 5 6 7 8)
+
+* *lst*
+(1 2 3 4 5)
+
+* (append (list -3 -2 -1 0) *lst*)
+(-3 -2 -1 0 1 2 3 4 5)
+
+* *lst*
+(1 2 3 4 5)
+
+* (append (list 0) *lst* (list 6))
+(0 1 2 3 4 5 6)
+
+* *lst*
+(1 2 3 4 5)
+```
+
+This means both that you may safely pass it any data you want appended without worrying about losing the original lists, and that if you want such behavior, you need to explicitly assign the result of `append` yourself.
diff --git a/1-04-17-circular-lists.md b/1-04-17-circular-lists.md
new file mode 100644
index 0000000000000000000000000000000000000000..5e325f7b0c3bf63b6719c3f9c4c39ce268b14b6d
--- /dev/null
+++ b/1-04-17-circular-lists.md
@@ -0,0 +1,41 @@
+# Exercise 1.4.17
+
+## Circular Lists
+
+The destructive equivalent of `append` is `nconc`. Using such side-effects, it's possible to create circular lists.
+
+```lisp
+* (defparameter *cycle* (list 'a 'b))
+*CYCLE*
+
+* (first *cycle*)
+A
+
+* (second *cycle*)
+B
+
+* (third *cycle*)
+NIL
+
+* (fourth *cycle*)
+NIL
+```
+
+Before we create an actual cycle, we need to tell the interpreter to print them (otherwise the request to print a circular list would never return; unlike Haskell, Common Lisp is not a lazy language by default).
+
+```lisp
+* (setf *print-circle* t)
+T
+
+* (nconc *cycle* *cycle*)
+#1=(A B . #1#)
+
+* (third *cycle*)
+A
+
+* (fourth *cycle*)
+B
+
+* (loop repeat 15 for elem in *cycle* collect elem)
+(A B A B A B A B A B A B A B A)
+```
diff --git a/1-04-18-circular-trees.md b/1-04-18-circular-trees.md
new file mode 100644
index 0000000000000000000000000000000000000000..6174e01d743b30ebc147dc192c111d3f04397977
--- /dev/null
+++ b/1-04-18-circular-trees.md
@@ -0,0 +1,51 @@
+# Exercise 1.4.18
+
+## Circular Trees
+
+The `nconc` procedure is fine when all you want is a simple cycle, but it's also possible to use direct mutation to create more elaborate structures.
+
+```lisp
+* (defparameter *knot* (list 1 2 3 4 (cons nil nil)))
+*KNOT*
+
+* (setf (car (nth 4 *knot*)) (cdr *knot*))
+#1=(1 2 3 4 (#1#))
+
+* (setf (cdr (nth 4 *knot*)) (cddr *knot*))
+#1=(3 4 ((1 2 . #1#) . #1#))
+```
+
+Now we've got a structure that branches back on itself twice.
+
+```lisp
+* (defun cycle-walk (count cycle &key (turn #'car))
+    (loop with place = cycle
+          repeat count for elem = (car place)
+          unless (consp elem) do (format t "~a " elem)
+          do (setf place (if (consp elem)
+			                 (funcall turn elem)
+			                 (cdr place)))))
+CYCLE-WALK
+
+* (cycle-walk 25 *knot* :turn #'car)
+1 2 3 4 2 3 4 2 3 4 2 3 4 2 3 4 2 3 4
+NIL
+
+* (cycle-walk 25 *knot* :turn #'cdr)
+1 2 3 4 3 4 3 4 3 4 3 4 3 4 3 4 3 4
+NIL
+
+* (let ((dir))
+    (defun switch (pair)
+      (setf dir (not dir))
+      (if dir
+	      (car pair)
+	      (cdr pair))))
+SWITCH
+
+* (cycle-walk 25 *knot* :turn #'switch)
+1 2 3 4 3 4 2 3 4 3 4 2 3 4 3 4 2 3 4
+NIL
+```
+
+Of course, it's possible to go further. Large, divergent "trees" that eventually cycle backwards from any number of branches at arbitrary depths. You'd build them the same way though; using some combination of `nconc`, `setf` along with `car`/`cdr` and friends.
diff --git a/1-04-19-quoting.md b/1-04-19-quoting.md
new file mode 100644
index 0000000000000000000000000000000000000000..4bcc0cada80c6635c5b57d39e6dcfeda6bac537a
--- /dev/null
+++ b/1-04-19-quoting.md
@@ -0,0 +1,45 @@
+# Exercise 1.4.19
+
+## Quoting
+
+Another way to construct tree structure is using the `quote` or `'`.
+
+```lisp
+* (quote (1 2 3))
+(1 2 3)
+
+* '(1 2 3)
+(1 2 3)
+
+* (list 1 2 3)
+(1 2 3)
+```
+
+The structures you create this way are equivalent.
+
+```lisp
+* (equal (quote (1 2 3)) '(1 2 3))
+T
+
+* (equal '(1 2 3) (list 1 2 3))
+T
+```
+
+The difference is that, while `list` essentially means "Return the list of these arguments", `quote`/`'` means "Return this argument without evaluating it".
+
+```lisp
+* (defparameter *test* 2)
+*test*
+
+* (list 1 *test* 3)
+(1 2 3)
+
+* '(1 *test* 3)
+(1 *test* 3)
+
+* (list (+ 3 4) (+ 5 6) (+ 7 8))
+(7 11 15)
+
+* '((+ 3 4) (+ 5 6) (+ 7 8))
+((+ 3 4) (+ 5 6) (+ 7 8))
+```
diff --git a/1-04-20-more-quoting.md b/1-04-20-more-quoting.md
new file mode 100644
index 0000000000000000000000000000000000000000..0783be330bb322c016e9c70b2c3ec8c0e765c965
--- /dev/null
+++ b/1-04-20-more-quoting.md
@@ -0,0 +1,37 @@
+# Exercise 1.4.20
+
+## More Quoting
+
+Because `quote` supresses evaluation, you can use it to more easily build deeply nested structures.
+
+```lisp
+* (list 1 (list 2 3) (list 4 (list (list 5) 6 7 8)))
+(1 (2 3) (4 ((5) 6 7 8)))
+
+* '(1 (2 3) (4 ((5) 6 7 8)))
+(1 (2 3) (4 ((5) 6 7 8)))
+```
+
+Take care not to use quoted data for mutation though. While the structures produced may be the same, mutating a quoted structure is undefined by the Common Lisp language spec, and is thus entirely implementation dependant.
+
+```lisp
+* (defvar *listed* (list 3 2 1))
+*listed*
+
+* (defvar *quoted* '(3 2 1))
+*quoted*
+
+* (push 4 *listed*)
+(4 3 2 1)
+
+* *listed*
+(4 3 2 1)
+
+* (push 4 *quoted*)
+???
+
+* *quoted*
+???
+```
+
+The question marks aren't there so you can figure out what the results are supposed to be. They signify that what you get back in these situations depends on which implementation of Common Lisp you're using. They may do incompatible things, but because the spec leaves this situation undefined, none of them are actually wrong. So, you know ... careful.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 472010e8a0a9c9c6fc10037dd5c4abe95ef4328e..907160275b56a193b9534c02e668f87fd95f713d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,17 @@
 # CHANGELOG
 
+## 2022-08-30
+
+- Chapter 1.4, "Lists and List Operations"
+    - Revised Exercise 1.4.1, restructuring into separate "In the REPL" and "What You Should See" subsections the way LxTHW books are supposed to be
+    - Split all exercises into separate documents and adjust Markdown formatting accordingly
+    - Renamed Exercise 1.4.10 from "Push and Pop" to "Stacks"
+    - Renamed Exercise 1.4.11 from "Pop" to "PUSH and POP"
+- Update TODO
+    - Reformatted as an unordered list because the version of GitBook for Gitlab Pages doesn't support Markdown checklists like the latest hosted GitBook platform does
+    - Removed entry for Chapter 1.4
+- Update TOC to reflect structural changes to Chapter 1.4
+
 ## 2022-08-29
 
 - Exercise 1.1.8, "Configuring Your Development Environment"
diff --git a/SUMMARY.md b/SUMMARY.md
index a94076e6063cc4efada78f7dc699a28a747fd175..ca5fc12b698b193ef285ce74e9f712d99509ace3 100644
--- a/SUMMARY.md
+++ b/SUMMARY.md
@@ -16,9 +16,9 @@
 
 ## PART ONE: GROKKING LISP
 
-* [Overview](1-0-0-overview.md)
-* [Common Lisp Bootcamp](1-01-00-lisp-bootcamp.md)
-    * [Syntax Overview in 5 Minutes](1-01-01-syntax-overview.md)
+* [Overview](./1-0-0-overview.md)
+* [Common Lisp Bootcamp](./1-01-00-lisp-bootcamp.md)
+    * [Syntax Overview in 5 Minutes](./1-01-01-syntax-overview.md)
     * [The REPL](./1-01-02-repl.md)
     * [Expressions, Parentheses, and Return Values](./1-01-03-expressions.md)
     * [Lists, Cons-Cells, and Memory](./1-01-04-lists-cons-cells.md)
@@ -48,6 +48,26 @@
     * [Pretty-Printing](./1-02-19-pretty-printing.md)
 * [Extra Credit: Getting Input from Users](./1-03-0-getting-input-from-users.md)
 * [Lists and List-Operations](./1-04-0-lists.md)
+    * [Cons-Cells](./1-04-01-cons-cells.md)
+    * [Consing](./1-04-02-consing.md)
+    * [Dot-Notation](./1-04-03-dot-notation.md)
+    * [More Consing](./1-04-04-more-consing.md)
+    * [CAR and CDR](./1-04-05-car-and-cdr.md)
+    * [More CAR and CDR](./1-04-06-more-car-and-cdr.md)
+    * [Lists](./1-04-07-lists.md)
+    * [More Lists](./1-04-08-more-lists.md)
+    * [Even More CAR and CDR](./1-04-09-even-more-car-and-cdr.md)
+    * [Stacks](./1-04-10-stacks.md)
+    * [PUSH and POP](./1-04-11-push-and-pop.md)
+    * [More PUSH and POP](./1-04-12-more-push-and-pop.md)
+    * [FIRST, REST, and LAST](./1-04-13-first-rest-last.md)
+    * [List Position](./1-04-14-list-position.md)
+    * [Appending](./1-04-15-appending.md)
+    * [More Appending](./1-04-16-more-appending.md)
+    * [Circular Lists](./1-04-17-circular-lists.md)
+    * [Circular Trees](./1-04-18-circular-trees.md)
+    * [Quoting](./1-04-19-quoting.md)
+    * [More Quoting](./1-04-20-more-quoting.md)
 * [Extra Credit: Look-up Lists and Trees](./1-05-0-lookups-trees.md)
 * [Numbers and Math](./1-06-0-math.md)
     * [Integers](./1-06-01-integers.md)
diff --git a/TODO.md b/TODO.md
index a3ce37034055d05195e2d2a255d4c783930a393b..f443d93366e5ea80ea13e91a2388e6b56b68c398 100644
--- a/TODO.md
+++ b/TODO.md
@@ -1,9 +1,8 @@
 # TODO
 
-- [ ] Chapter 1.3, "Extra Credit: Getting Input From Users"
-    - [ ] Finish code examples
-    - [ ] Split code examples into separate "In the REPL" and "What You Should See" sections
-- [ ] Rewrite code examples and simplify discourse for Chapter 1.4, "Lists and List Operations"
-- [ ] Rewrite code examples and simplify discourse for Chapter 1.5, "Extra Credit: Look-up Lists and Trees"
-- [ ] Write code examples for Chapter 1.7, "Extra Credit: Arrays and Vectors"
-- [ ] Write code examples for Chapter 1.8, "Variables, Parameters, and Constants"
+- Chapter 1.3, "Extra Credit: Getting Input From Users"
+    - Finish code examples
+    - Split code examples into separate "In the REPL" and "What You Should See" sections
+- Rewrite code examples and simplify discourse for Chapter 1.5, "Extra Credit: Look-up Lists and Trees"
+- Write code examples for Chapter 1.7, "Extra Credit: Arrays and Vectors"
+- Write code examples for Chapter 1.8, "Variables, Parameters, and Constants"