On May 22, 9:51 pm, Pedro Teixeira <pedr...@gmail.com> wrote: > On Apr 27, 9:45 am, Rich Hickey <richhic...@gmail.com> wrote: > > > > > > > On Apr 27, 2010, at 3:20 AM, Mark Engelberg wrote: > > > > Watching Stuart's tutorial, it looks like the automaticfactory > > > functions for deftypes have gone away (I'm still working with Clojure > > > 1.1, so haven't had a chance to try the latest changes for myself). > > > I'm going to miss that feature, especially fordefrecord, which is now > > > the "common case" construct. > > > > I understand that you can always do "Foo." to construct a Foo record, > > > but these constructors don't act as full-fledged functions, right? > > > > Honestly, for me the main issue is just that subjectively, it is less > > > satisfying to create a Clojure data structure and end up with > > > something that you construct with Java interop syntax. I'd like > > > Clojure data structures to look and feel "Clojurish" not "Javaish" > > > (yes, I know that Clojure is built with interop in mind, so > > > technically, anything Javaish is also Clojurish, but I still feel a > > > difference). > > > I agree. I asked for suggestions for thefactoryfn in #clojure, but > > got some pushback against introducing things in the namespace. I'm > > still open to suggestions, here are the issues: > > > The generated type name is now imported, so at the very least the > > factoryfn can't have the same name as the class. Alternatives are > > create-Foo etc. > > > Some have asked for parameterized factories: > > > (record Foo ...) or (record ::Foo ...) > > > These cannot be made as fast as direct factories. Also, they may be > > used for key/value initialization: > > > (record ::Foo :field1 v1 :field2 v2 ...) > > > As soon as people want bodies for the factories, in order to do > > argument transformation/validation/defaulting, a generatedfactoryis > > in the way. > > > We left it at: If you really want afactoryyou can always write one, > > let's see if people do. > > Thought a dynamic factory is usefull. Here it goes my first macro, so > please let me know if I'm silly here. > > (defmacro record > "Dynamic factory for defrecords." > ([name] `(record ~name {}) ) > ([name vals-map] > (let [num-fields > (alength (.getParameterTypes (first (.getDeclaredConstructors > (class name))))) > args (repeat num-fields nil)] > `(merge (new ~name ~...@args) ~vals-map)))) > > Usage: > (defrecord Bar [x y]) > (record Bar) >
That previous attempt was not good. For any one interested, the following macro might do the job: (defmacro record "Dynamic factory for defrecords." ([name] `(record ~name {}) ) ([name vals-map] `(let [con# (first (.getDeclaredConstructors ~name)) num# (alength (.getParameterTypes con#))] (merge (.newInstance con# (make-array Object num#)) ~vals-map)))) So we can maintain a dynamic relation with defrecord: (defrecord Bar [x y]) (record Bar) (record Bar {:x 1)) cheers, Pedro -- 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