In any case, here is how a record-factory function would look like (credit goes to Chris Houser if I'm not mistaken):

(defn record-factory "A factory function for records." [recordname]
  (let [recordclass ^Class (resolve (symbol recordname))
        max-arg-count (apply max (map #(count (.getParameterTypes %))
                                      (.getConstructors recordclass)))
        args (map #(symbol (str "x" %)) (range (- max-arg-count 2)))]
    (eval `(fn [~@args] (new ~(symbol recordname) ~@args)))))

(defn record-factory-aux
"Same as record-factory but using the auxiliary constructor of records which accepts a meta-data map and a field extension map as extra args. " [recordname]
  (let [recordclass ^Class (resolve (symbol recordname))
        max-arg-count (apply max (map #(count (.getParameterTypes %))
                                      (.getConstructors recordclass)))
        args (map #(symbol (str "x" %)) (range max-arg-count))]
    (eval `(fn [~@args] (new ~(symbol recordname) ~@args)))))

One can do whatever he wants with 'args' before passing them in...This has solved a lot of my problems!

Jim


On 05/08/12 10:56, Vinzent wrote:
+1 for Warren's proposal. I thought about the same thing earlier, but haven't shared it with community because I believed it'd be rejected.

Though, I don't see how OOP relates to the topic of this discussion. Records are not objects; they are rather typed maps. Everyone writes that "constructor" (or "factory") functions. It's perfectly legal and there is nothing shameful (e.g. OO-like) in it.

In my mind, the problem is that Sean says that it's standard practice to create "make-Foo" function, while tbc++ believes it's idiomatic to name it "foo". In other words, we have a very common and basic pattern, but it's not covered by an appropriate abstraction. The result of that is unnecessary and meaningless complication of reading code. Compare it with Java: constructor (and the factory pattern too, but to a lesser extent because of limitations of the language) is a standard, built-in construct; the reader knows where to look at to learn how a class instantiates.

On the other hand, it looks like many clojure folks prefer to use plain maps where records could be used because of countless limitations and warts of the latter, which makes the proposed change less useful than it could be.
--
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

Reply via email to