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

Reply via email to