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

Section 7.9 of David Touretzky’s Gentle Introduction to Common Lisp (Download) introduces the reduce operator. Given two inputs, a function and a list, this applicative operator reduces the elements of the input list to a single result value. reduce might be seen as a variant of apply. It’s very intuitive. See this Lisp example:

and the same in Clojure:

There is no direct equivalent for append in Clojure. There is a function conj, but applying it to the input list (here: a list of lists) doesn’t produce the output that we want:

The into function creates a new collection by conjoining all elements of the input collection:

But as you can see, this isn’t enough. With reduce the respective elements of the input collection are ‘melted’ into a single collection. (This collection might be a list, a vector, or whatever.) But we are running off the track.

Exercise 7.16 makes us write a function that collapses a list of sets into a single set. Note that a set is defined by the uniqueness of its members, so no element must appear more than once in the result set.

Exercise 7.17 asks for a function with a list of lists as input that calculates the total length of this list.

This is the Lisp code for exercises 7.16 and 7.17:

And this is the same code written in Clojure:

Omitting duplicates in Lisp is done by calling remove-duplicates. Clojure’s distinct does the same thing. The original sets that were appended (Lisp) or into’d lose their duplicates this way, a very concise solution. There are two different solutions for exercise 7.17, respectively. Both are correct, but the second one results in better performance, at least in Lisp, because each append in the first solution creates cons actions that consume a lot of memory. I’m not sure if this is still true for the Clojure versions, but I’m giving you both solutions, anyway.

Exercise 7.18 wants to know why (reduce #’+ nil) returns 0 and (reduce #’* nil) returns 1. For answering this, we need a bit of math. Given two lists x and y, then

should be equivalent to

– that is the sum of the sums of x and y, respectively. If y is NIL, then (append x y) evaluates to x; so (reduce #’+ y) must result in 0. This makes 0 the identity value for addition, and this is the reason why calling ‘+’ with no arguments results in 0. 1 is the identity value for multiplication, so calling ‘*’ with no arguments results in 1.

Here you can see it the Lisp way:

And so it’s called in Clojure:

See part 1, part 2, part 3, part 4 of this series.

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.