3
votes

I'm trying to understand how clojure macros apply to lists. I'm confused by the following:

(defmacro islist [f] (list? f))
(islist (1 2)) ; true
(islist '(1 2)) ; false
(islist (quote (1 2))) ; true

Is this expected? I've noticed that lists I pass to to macros return false when evaluated with list? inside the macro. That is, the second example is particularly confusing.

1
You sure you don't want this? (defmacro islist[f] `(list? ~f))Bill

1 Answers

2
votes

Within the macro '(1 2) is of type clojure.lang.Cons (you can check this by changing list? to type). list? returns true iff the operand is of type clojure.lang.IPersistentList.

user=> (isa? clojure.lang.Cons clojure.lang.IPersistentList)
false

The reason clojure.lang.Cons appears is because the reader constructs a cons cell when expanding '(1 2) to (quote (1 2)), whereas it doesn't when you spell out quote directly as (quote (1 2)).

You probably want to use seq? instead of list?.