Yesterday I made it through Chapter 2 and as before I've enjoyed it. I have come to copy the question/answer style from the book into the tests:
First I write the application of the function under test, then the expectation such as:
```clojure
(is (= (lat? '(Jack Sprat could eat no chicken fat)) true))
```
I understand that calling functions recursively, as done in the book, isn't idiomatic in Clojure.
```clojure
(def lat?
(fn [l]
(cond (null? l) true
(atom? (car l)) (lat? (cdr l))
:else false)))
```
There's `recur` for that. For now, I like to continue with calling functions regardless. The data-size is small and, since I have tests in place, once I'm through with the book, I can imagine a refactor using `recur`.
On the same note, I recognize that Clojure has great helper functions such as `every?` that I could leverage directly. For example, the above mentioned function `lat?` could become a one-liner such as by asking "is every expression in the list not a list itself".
```clojure
(def lat?
(fn [l]
(every? #(not (list? %))) l)))
```
This is much cleaner (and every? Itself is a recursive function) but in the spirit of the book, I'm going to stick with the functions as they are discussed. Again, my test-suite will allow for refactoring as needed later.
Lastly, I am getting into the habit of tiny, regular commits. I now make a commit when I have fully tested a function just before moving on to the next one. I can see even smaller commits on every red-to-green test cycle.
If you are interested, the full listing for Chapter 2 is as follows:
```clojure
(ns the-little-clojurian.chapter2
(:require [clojure.test :refer :all]
[the-little-clojurian.chapter1 :refer :all]))
(with-test
(def lat?
(fn [l]
(cond (null? l) true
(atom? (car l)) (lat? (cdr l))
:else false)))
(testing "returns true"
(is (= (lat? '(Jack Sprat could eat no chicken fat)) true))
(is (= (lat? '()) true))
(is (= (lat? '(bacon and eggs)) true)))
(testing "returns false"
(is (= (lat? '((Jack) Sprat could eat no chicken fat)) false))
(is (= (lat? '(Jack (Sprat could) eat no chicken fat)) false))
(is (= (lat? '(bacon (and eggs))) false))))
(deftest boolean-operators
(is (= (or (null? '())
(atom? '(d e f g)))
true))
(is (= (or (null? '(a b c))
(null? '()))
true))
(is (= (or (null? '(a b c))
(null? '(atom)))
false)))
(with-test
(def member?
(fn [a lat]
(cond (null? lat) false
:else (or (eq? (car lat) a)
(member? a (cdr lat))))))
(testing "evaluates to true"
(is (= (member? 'meat '(meat)) true))
(is (= (member? 'tea '(coffee tea and milk))))
(is (= (member? 'meat '(mashed potatoes and meat gravy)) true)))
(testing "evaluates to false"
(is (= (member? 'meat '()) false))
(is (= (member? 'liver '(bagels and lox)) false))
(is (= (member? 'poached '(fried eggs and scrambled eggs))))))
```