When I try to run the following code from the REPL (playing with dynamic records):
(defrecord (symbol "rec2") (vec (map symbol ["f1" "f2"])))
I receive the error CompilerException java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol, compiling:(NO_SOURCE_PATH:23)
I’m asking myself where I generate this PersistentList considering that:
user=> (symbol "rec2")
rec2
user=> (vec (map symbol ["f1" "f2"]))
[f1 f2]
But my real question is why the following code works:
user=> (defrecord rec2 [f1 f2])
user.rec2
I’ve also tried:
user=> (clojure.core/defrecord (clojure.core/symbol "rec1") (vec (clojure.core/map clojure.core/symbol ["f1" "f2"])))
CompilerException java.lang.RuntimeException: Can't refer to qualified var that doesn't exist, compiling:(NO_SOURCE_PATH:40)
(qualified var? The only difference is that I’m fully qualifying function names WHICH EXIST, BTW)
Obviously I’m missing something in my understanding of Clojure defrecord macro, but I thought that macro are simply AST modifiers so if I give it a symbol or something that resolves to a symbol it’s the same thing, so I would like someone to explain me why the normal form works and the others not!
TIA!
The problem is following:
defrecordis a macro and all arguments are not evaluated. They passed to macro, so it gets(symbol "rec2")– list that contains 2 elements: symbol and string, notrec2as you expect. You can try following:It creates list
(defrecord rec2 [f1 f2])and then evaluates it.But I don’t think that it’s good idea to eval some code dynamically. May be there is some other way to do it.