In the second article he shows how to write a program to list primes using
filter rather than
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
filterfunction 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
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 . 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 . 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
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.
 In Clojure function calls provide arguments in a list, but function definitions gather arguments into vectors.