A quick experiment under Clojure repl:
> (class '@foo)
clojure.lang.PersistentList
This is more or less expected, so let's wrap the same expression in a def
:
> (def x '@foo)
> (class x)
clojure.lang.Cons
I tried playing with def
and various other forms but '@foo
seems to be the only one that triggers this behavior.
I tried this in a fresh REPL and reproduced the behavior.
There is a convoluted explanation for the specific behavior you are seeing. You have uncovered a peculiar corner in the Clojure reader.
The @
character is a "reader macro" that is shorthand for the following:
@xxx => (deref xxx)
The '
character is another reader macro that is also shorthand for:
'yyy => (quote yyy)
Put them together and you get
'@zzz => (quote (deref zzz))
So the quote
special form comes first. It says, "treat everything enclosed here as a data structure, not as executable code".
The data structure (deref zzz)
is a list containing 2 symbols, deref
and zzz
.
With regards to the difference in the class
between a literal and a Var, we see:
user=> (def bbb '@foo)
#'user/bbb
user=> (class bbb)
clojure.lang.Cons
user=> (def ccc (quote (deref foo)))
#'user/ccc
user=> (class ccc)
clojure.lang.PersistentList
Using "object oriented" lingo, a Cons
, PersistentList
, PersistentVector
, and LazySeq
are all "subclasses" of the generic "Seq" type in Clojure. They can all be used interchangably, and the unexpected difference in the 2 classes above is an unimportant implementation detail.