Search code examples
listclojurelispcons

Why is `(a) read as a list while `(a b) isn't?


While learning clojure, I was very surprised to find out that these two objects are different types:

(list? `(inc))   ;; true
(list? `(inc 1)) ;; false

In theory, I understand why the second form returns false, that object is actually a clojure.lang.Cons. In practice, though, I don't understand why that is happening.

Why does the reader read `(inc) different from `(inc 1)? What is happening under the hood?


Solution

  • When the reader encounters a syntax-quoted form, that turns out to be a collection, it will iterate over each element and call syntax-quote recursively. The result is consed, beginning with nil.

    So it comes down to the question why the following holds:

    > (list? (cons 'inc nil))
    true
    > (list? (cons 'inc (cons 1 nil)))
    false
    

    This seems to be a matter of definition.