# A wrinkle in Clojure

Bob Martin recently posted a nice pair of articles, A Little Clojure and A Little More Clojure. In the first article he talks about how spare and elegant Clojure is.

In the second article he shows how to write a program to list primes using `map` and `filter` rather than `if` and `while`. He approaches the example leisurely, showing how to arrive at the solution in small steps understandable to someone new to Clojure.

The second article passes over a small wrinkle in Clojure that I’d like to say a little about. Near the top of the post we read

The `filter` function also takes a function and a list. `(filter odd? [1 2 3 4 5])` evaluates to `(1 3 5)`. From that I think you can tell what both the `filter` and the `odd?` functions do.

Makes sense: given a bunch of numbers, we pick out the ones that are odd. But look a little closer. We start with `[1 2 3 4 5]` in square brackets and end with `(1 3 5)` in parentheses. What’s up with that? The article doesn’t say, and rightfully so: it would derail the presentation to explain this subtlety. But it’s something that everyone new to Clojure will run into fairly quickly.

As long as we’re vague about what “a bunch of numbers” means, everything looks fine. But when we get more specific, we see that `filter` takes a vector of numbers and returns a list of numbers [1]. Or rather it can take a vector, as it does above; it could also take a list. There are reasons for this, explained here, but it’s puzzling if you’re new to the language.

There are a couple ways to make the filter example do what you’d expect, to either have it take a vector and return a vector, or to have it take a list and return a list. Both would have interrupted the flow of an introductory article. To take a vector and return a vector you could run

`    (filterv odd? [1 2 3 4 5])`

This returns the vector `[1 3 5]`.

Notice we use the function `filterv` rather than `filter`. If the article had included this code, readers would ask “Why does filter have a ‘v’ on the end? Why isn’t it just called ‘filter’?”

To take a list and return a list you could run

`    (filter odd? '(1 2 3 4 5))`

This returns the list `(1 3 5)`.

But if the article had written this, readers would ask “What is the little mark in front of `(1 2 3 4 5)`? Is that a typo? Why didn’t you just send it the list?” The little mark is a quote and not a typo. It tells Clojure that you are passing in a list and not making a function call.

One of the core principles of Lisp is that code and data use the same structure. Everything is a list, hence the name: LISP stands for LISt Processing. Clojure departs slightly from this by distinguishing vectors and lists, primarily for efficiency. But like all Lisps, function calls are lists, where the first element of the list is the name of the function and the remaining elements are arguments [2]. Without the quote mark in the example above, the Clojure compiler would look in vain for a function called 1 and throw an exception:

CompilerException java.lang.RuntimeException: Unable to resolve symbol: quote in this context, compiling: …

Since vectors are unambiguously containers, never used to indicate function calls, there’s no need for vectors to be quoted, which simplifies the exposition in an introductory article.

## More Lisp posts

[1] The `filter` function actually returns a lazy sequence, displayed at the REPL as a list. Another detail one would be wise to omit from an introductory article.

[2] In Clojure function calls provide arguments in a list, but function definitions gather arguments into vectors.

## 2 thoughts on “A wrinkle in Clojure”

1. “A wrinkle in…” Well, Clojure would not have been the next word on the tip of my tongue. I’d have leaned toward something a bit more L’Engle-ish.

2. Christian Lynbech

I am no authority on the core principles of Lisp but I know of no Lisp implementation where everything is a list.

Certainly, Common Lisp has both lists and vectors as separate data types. They are however both sequences and a number of Common Lisp functions (including `map’, `find’ and `remove’) will work on any sequence type.

To me, one core principle of Lisp is more that code (e.g. function calls) are also first-class data structures (which indeed are lists) and as ou point out, this holds for Clojure.