Question on defrecord
I tried to assign a data type to a var and then instantiate it using the var, but it doesn't seem to work: user= (defrecord X []) user.X user= (X.) #:user.X{} user= X user.X user= (def hey X) #'user/hey user= (hey.) java.lang.IllegalArgumentException: Unable to resolve classname: hey (NO_SOURCE_FILE:59) user= (new X) #:user.X{} user= (new hey) java.lang.IllegalArgumentException: Unable to resolve classname: hey (NO_SOURCE_FILE:61) user= (apply new hey) java.lang.Exception: Unable to resolve symbol: new in this context (NO_SOURCE_FILE:62) Can anybody help me understand how to accomplish this when using the var? This will give me a generic way to instantiate the type when I know the parameters. Regards, Shantanu -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Question on defrecord
On Aug 11, 7:03 pm, Shantanu Kumar kumar.shant...@gmail.com wrote: I tried to assign a data type to a var and then instantiate it using the var, but it doesn't seem to work: user= (defrecord X []) user.X user= (X.) #:user.X{} user= X user.X user= (def hey X) #'user/hey user= (hey.) java.lang.IllegalArgumentException: Unable to resolve classname: hey (NO_SOURCE_FILE:59) user= (new X) #:user.X{} user= (new hey) java.lang.IllegalArgumentException: Unable to resolve classname: hey (NO_SOURCE_FILE:61) user= (apply new hey) java.lang.Exception: Unable to resolve symbol: new in this context (NO_SOURCE_FILE:62) Can anybody help me understand how to accomplish this when using the var? This will give me a generic way to instantiate the type when I know the parameters. Regards, Shantanu There is no way to do this without using Java reflection, see e.g. user= (defrecord A []) user.A user= (def x A) #'user/x user= (.newInstance x) #:user.A{} user= Note .newInstance is a simple example and only works for no-arg constructor. See, e.g., http://download.oracle.com/javase/tutorial/reflect/member/ctorInstance.html -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Question on defrecord
On Wed, Aug 11, 2010 at 1:03 PM, Shantanu Kumar kumar.shant...@gmail.com wrote: I tried to assign a data type to a var and then instantiate it using the var, but it doesn't seem to work: user= (defrecord X []) user.X user= (X.) #:user.X{} user= X user.X user= (def hey X) #'user/hey user= (hey.) java.lang.IllegalArgumentException: Unable to resolve classname: hey (NO_SOURCE_FILE:59) user= (new X) #:user.X{} user= (new hey) java.lang.IllegalArgumentException: Unable to resolve classname: hey (NO_SOURCE_FILE:61) user= (apply new hey) java.lang.Exception: Unable to resolve symbol: new in this context (NO_SOURCE_FILE:62) Can anybody help me understand how to accomplish this when using the var? This will give me a generic way to instantiate the type when I know the parameters. The problem is that X. is a special form, so when you say hey. it's looking for a class literally named hey. The best solution is to provide for each defrecord a real Clojure function to act as a factory. There are several places that such a function can be helpful, and in real-world code you almost always run into at least one of them: (defrecord X []) (defn new-X [] (X.)) (def hey new-X) (hey) ;= #:user.X{} If you don't like the idea of a named factory function for each record type, you can create an anonymous fn on the fly instead: (defrecord X []) (def hey #(X.)) (hey) ;= #:user.X{} Note in either case when you define the factory fn (named or not), you need to specify all the args the real record constructor requires. --Chouser http://joyofclojure.com/ -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Question on defrecord
Hi Shantanu, It depends on exactly what you want when you say accomplish this. The Clojure (new Foo) and (Foo.) forms map to Java new. You cannot call Java new generically, from any Java language. You have to have a class already in hand. If you want genericity at compilation time, you could write a macro that expands to a new form. But probably what you want is genericity at runtime. For this, you need to use Java reflection to instantiate the class. There is a previous thread on this that includes some sample code [1], but nothing in Clojure (yet). It is fairly easy to write a reflective factory that is good enough for a single app or library, but harder to write one that is general enough to be in Clojure proper. There is an outstanding ticket that would cover this [2] and it will probably get into the release of Clojure after 1.2. Stu [1] http://groups.google.com/group/clojure/browse_thread/thread/bd7be7bd373eadba/4bc3e7a2099ad72d [2] https://www.assembla.com/spaces/clojure/tickets/374-print-read-syntax-for-defrecords I tried to assign a data type to a var and then instantiate it using the var, but it doesn't seem to work: user= (defrecord X []) user.X user= (X.) #:user.X{} user= X user.X user= (def hey X) #'user/hey user= (hey.) java.lang.IllegalArgumentException: Unable to resolve classname: hey (NO_SOURCE_FILE:59) user= (new X) #:user.X{} user= (new hey) java.lang.IllegalArgumentException: Unable to resolve classname: hey (NO_SOURCE_FILE:61) user= (apply new hey) java.lang.Exception: Unable to resolve symbol: new in this context (NO_SOURCE_FILE:62) Can anybody help me understand how to accomplish this when using the var? This will give me a generic way to instantiate the type when I know the parameters. Regards, Shantanu -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en