This is the second Chapter of a series of posts about porting The Little Schemer to Clojure. You may wish to read the intro.
This chapter introduces functions – and the idea of the list of atoms and the member
function.
When looking at list atoms, known as a 'lat'
we are introduced to writing functions in Scheme. We write the lat?
function in Clojure to test for a non-nested list of atoms.
(def lat?
(fn [l]
(cond
(null? l) true
(and (seq? l)
(atom? (first l)))
(lat? (rest l))
true false)))
There are a couple of things we’ve transposed here. The key one to raise is the usage of def... fn[]
rather than defn
. This is a convention in the book, and glues in the readers minds that functions are by default anonymous, and we give them labels after the fact. This enables the reader to get into the feel of passing anonymous functions around later.
The other thing that is introduced here is the application of the Ten Commandments (of The Little Schemer). The big ideas of the 10 Commandments is to help you solve problems recursively. The first one states that you should always ask null?
as the first question in expressing any function. In idiomatic Clojure we would use the empty?
function for this – but for the sake of being closer to the book, we will not apply it in this function, but use null?
.
The question behind this is what is a non-nested list of atoms and why do we care? One of the big themes in this book is solving problems using recursion rather than iteration. The point is that before you can solve a problem using recursion (where you’ve got a nested list) you need to learn to solve it for the base case where there is no nested list. To validate the base case – we use the lat?
function.
The next function we look at is the member?
function.
(def member?
(fn [a lat]
(cond
(null? lat) false
true (or
(= (first lat) a)
(member? a (rest lat)))) ))
Why do we have this function? It’s the first useful function in the book. We also keep building our recursion skills, and it is a key building block for later functions.
You can see it working here.