for setting up objects as you say, I'm fine using (doto Object ... ... ...). Records, as everything else in Clojure promote immutability and so setting fields doesn't really make sense unless you're consuming external java classes in which case 'doto' suffices...at least that is the way I see it...I originally thought you were asking about how to create a record at runtime via a macro or a function, which is actually quite tricky (and I can certainly help), but what you're asking sort of exists doesn't it?

Jim


On 04/08/12 17:44, Warren Lynn wrote:
My vague impression is this has been discussed somewhere, but I did not find a ticket in Jira when searching on "record, constructor", so I want to have some discussion here before considering entering a ticket myself.

Often, when I create a record, I need to do some set-up more than just pass the values to the fields (like to set the field values derived from some arguments, or add extra map keys when needed. Regular common OO constructor thing). Or course, I can do this:

(defn make-myrecord [....]   ... )

But I don't like the ad-hoc nature of that. Besides personal taste, whenever a common use case pattern is not captured and defined in the language, it just makes further abstraction and writing generic code more difficult.

So what I have now is this:

(defmulti make-record
  "Create a new record. The first argument should be the record type (like
  MyRecord). Kind of like a constructor for record.

  Example method definition:
  (defmethod make-record MyRecord
  [rectype arg1 arg2 ...] ...)"
  (fn [& args] (first args)))

This works but has one downside: it involves unnecessary run-time dispatch on the type. Although there are cases we may need dynamic creation of a record with run-time record type, most of time the record type is just static that can be decided at compile time (again, just like "new MyClass(a, b, c) as in common OO languages).

So, as you may have guessed out from the title and the above, I think if we can have a mechanism to define constructors in "defrecord", that seems a nice feature to me. What's on my mind is something like this:

(defrecord MyRecord
    [x y z]
  (make-record "My constructor 1" [arg1 arg2] ...)
  (make-record "My constructor 2" [arg1 arg2 arg3 ...] ...))

(make-record MyRecord arg1 arg2 arg3 ...) ;; this creates a new record. no need of run-time dispatching

Just like the constructors in common OO languages, constructors will:

1. Clearly communicates the designer's intention how the record should be created and avoid insistent internal field values. By the way, the doc strings in all constructors will also help, as everything in in one place. 2. Provides more regularity in the language, which can smooth/help further abstractions (for example, certain macros).

I know mentioning OO may be a big turn-off for certain people, but I don't see a clash here. Immutable objects are still objects and certain boring but widely accepted practice from OO may still apply here.

I had a brief look at "defrecord2" (https://github.com/david-mcneil/defrecord2), which certainly enhanced things. But because it is not part of the language itself, it feels patchy (I think even the author is not happy about that). Also, in general I would avoid creating functions behind the scene based on naming manipulations, especially for low level constructs.

Any comments? Thank you.

--
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