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 [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en