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

Reply via email to