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