Clojure: A Gentle Introduction (Chapter 7, Part 3)

Before coming to exercises 7.8 – 7.10 let us discuss the find-if operator first. Find-if takes a predicate and a list as input and ‘returns’ the first element matching the predicate. (Why ‘returns’? Because functions always evaluate to something, they don’t give you back. Looks like it’s the same, but Lisp / Clojure gets easier when you think of evaluating functions whenever you see a pair of brackets.) So,

Of course, a lambda expression as predicate is possible, too:

There’s no such thing as find-if in Clojure! Clojure uses the more generic filter function instead. So we can define our own simple find-if with this little function:

Calls this function like this:

…and find-first finds you the first even element of the input collection. filter takes f (here: the even? predicate) as input and applies it to the collection ‘(1 3 5 6 7). This evaluates to the list (6). Take the first element of it and you get 6. Not that difficult, is it?

Exercise 7.8 asks for a function with two inputs x (a list) and k (a value), that returns the first number in the list that is roughly equal to k (that means k-10 < number < k+10). Exercise 7.9 makes you write find-nested that returns the first element of a list that is itself a non-nil list.

Let us first care about these exercises before proceeding to exercise 7.10.

This is the Lisp code for these exercises:

And this is the same code in Clojure:

Note the differences: both roughly-equal versions are using lambda expressions in their appropriate dialect. These are applied to find-if (Lisp) and filter (Clojure), respectively. Note the extra first in the Clojure expression due to filter returning a list.

find-nested in both dialects also has similar differences and similarities. A list that is not empty is “not null” in Lisp and “not empty?” in Clojure, but the basic mechanism is the same in both functions. The applicative operator takes a function / predicate / lambda expression and a list as input. Each element e of the input list x wanders through the predicate and is tested for emptiness. The first match is returned.

Exercise 7.10 is a “mini keyboard exercise”. That is a more complex program consisting of cohering functions, here: a program to transpose a song from one key to another.

Exercise 7.10.a: Write a table for the correspondence between notes and numbers for a one-octave scale.

Exercise 7.10.b: Write a function numbers that takes an input list of notes and returns its corresponding numbers.

Exercise 7.10.c: Write a function notes that works the other way round.

Exercise 7.10.d is a comprehension question. Exercise 7.10.e makes you write the function raise that takes a number n and a list of numbers as input and raises each number in the list by the value n.

Exercise 7.10.f asks for a function normalize that takes a list of numbers as input and normalizes then to make them be between 1 and 12.

Exercise 7.10.g makes you write transpose, a function that takes a number n and a song as input, and that returns the song transposed by n half steps.

I’ve just summarized the tasks here; if you want to work through the exercises I really recommend downloading Touretzky’s book here (the edition from 1990). It’s free (and legal). Or buy the book and support Dover Publications.

This is the Lisp code:

And this is the Clojure version:

The differences start already in the beginning, because there are no association lists in Clojure. We take something better: a map. Every note is a key with its matching number as value. This has some influence on function calls. While it’s

in Lisp, the Clojure call looks like this:

Accessing Lisp’s members of association lists is done with functions like assoc; the same is done with get on Clojure’s maps. Apart from that you will recognize most of Lisp’s code in its modern cousin language. The different data structures are the main difference; everything else is just syntax.

See part 1 and part 2 of this series. To be continued.

About Manfred Berndtgen

Manfred Berndtgen, maintainer of this site, is a part-time researcher with enough spare time for doing useless things and sharing them with the rest of the world. His main photographic subjects are made of plants or stones, and since he's learning Haskell everything seems functional to him.