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

Traveling the world of applicative operators, section 7.8 of David Touretzky’s Gentle Introduction to Common Lisp introduces the remove-if and the remove-if-not operator. Both work like the operators we have met in part one, two, and three of this chapter: they take a function (or better: a predicate) and a list as input. Where remove-if removes all elements of the input list that are true for the given predicate, remove-if-not leaves exactly these and removes those elements that don’t match the predicate. Instead of using a predicate like #’oddp you can also use lambda expression. Nothing new so far if you have read the past articles and tried the exercises.

Exercise 7.11 asks you to write a function to pick out numbers in a list that are greater than 1 and less than 5.

Exercise 7.12 lets you write a function that’s counting how often the word ‘the’ appears in a sentence.

Exercise 7.13 wants you to pick only lists of length two in a list of lists.

Exercise 7.14 makes you implement functions intersection and union using remove-if and remove.

This is the Lisp code for these exercises:

And this is the same code in Clojure:

Let’s discuss this code briefly: gt1-gt5 is almost identical in both languages, apart from a few syntax differences. However, Clojure doesn’t know a remove-if-not, so the “not” part wanders from remove to the lambda part, but the result is the same.

Counting the “the”s in a sentence (a list) is also almost identical in both cases: we eliminate every element not equal to ‘the’ in the list and count the remaining elements. The differences are subtle, though: Lisp’s length is a count in Clojure. We already know there’s no remove-if-not, so Clojure’s remove makes us use a slightly different test for the word comparison: (not= word ‘the’) is the shortcut version of (not (= word ‘the)). Note the simplified = that subsumes the many other equality tests in Lisp.

The same applies to the no-more-than-two function.

We have to reach back a bit for exercise 7.14: the implementations of setdiff and intersection in Lisp make use of Lisp’s practical member function which doesn’t exist in Clojure. Member, as the name implies, tells you if an element is present in a list. It does so by not telling you just true or false, but by returning the element and the following elements of the input list. You can see three simple emulations of this member function for Clojure. All of them are rather primitive, because they don’t support keywords like the Lisp original, but each one will do what we want from it.

Having this member defined, the Clojure versions of setdiff, intersection, and union strongly look like the versions written in lisp. Only my-union appears to be a bit more complex. Maybe somebody wants to send me a better implementation.

Exercise 7.15 is a mini keyboard exercise that makes you write a simple card game. I won’t summarize the problem definitions here, you will find them in Toretzky’s book which is available for download on his website.

This is the Lisp code for exercise 7.15:

And this is the same code written in Clojure:

In 7.15b you can see that we again transformed Lisp’s association list into a map for Clojure. Clojure doesn’t know association lists, but maps are more powerful, anyway. my-hand and colors have become maps, and the bigger differences between the Lisp and Clojure versions concern accessing data: where it’s list accessor function like first and second in Lisp, you are using get for accessing map data in Lisp. The overall logic of the Clojure functions is the same like in its Lisp counterparts.

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.