Why can't I bind defrecord in clojure?
I have something like this:
user> (defrecord vertex [id val]) => user.vertex
user> (def v vertex) => #'user/v
user> (= v vertex) => true
user> (type v) => java.lang.Class
user> (type vertex) => java.lang.Class
user> (vertex. 1 2) => #user.vertex{:id 1, :val 2}
user> (v. 1 2) => "Unable to resolve classname v"
user> (new v 1 2) => "Unable to resolve classname v"
So basically I cannot bind a vertex to a different name. It's the same with trying to pass the defrecord type to a function, or let, or whatever. Why is this, and what can I do to temporarily rename the defrecord?
I guess this is a Java interop related trick.
source to share
defrecord
generates a Java class, which in my opinion is actually viewed as a form of special case in Clojure, specifically with regard to interoperability (although I'm not sure).
If your goal is to be able to easily bypass a function that can create vertices, then the solution is to use a local function that calls the constructor rather than doing the interop itself.
In Clojure 1.3, deftype and defrecord automatically generate two additional methods:
-
->{type}
equivalent to constructor -
map->{type}
takes a map of arguments as an argument
For the above, (->vertex 1 2)
both (map->vertex {:id 1 :val 2})
work and allow you to complete the construct you are doing.
If you really want a class that is accessible as you go through it, there might be something you can do with macros, although I'm not sure.
source to share
This is not possible as far as I know.
If you are thinking about how defrecord works; The bytecode actually generates the (java) class. You can see this in action when you do defrecord in one namespace and want to use it in another ...
(ns my-first-namespace)
(defrecord Foo [x y])
(ns my-second-namespace
(:use my-first-namespace)
(:import my_first_namespace Foo)) ; still have to import the java class
; underlying the defrecord even tho
; the defining namespace is use'd (note
; hyphen / underscore changes).
Unfortunately, in java (really in the JVM) there is no way to list a class name to another class. The closest you can get is subclassing to the new name, but that's pretty crude.
source to share