Hi,

I must admit my thoughts are still not fixed concerning this, guided
by several considerations:

* consider the ring spec: it specifies what keys are expected to be
present in the request map, the response map. Good enough.
  * Wait ! what if some keys could be calculated from others (derived)
=> they may not be essential, put them in a function.
  * Wait ! what if the computation of the value of the derived key heavyweight ?
     * answer 1 : let the consumer "cache" it.
     * answer 2 : "cache" the value in the map, but make it clear that
it costs something to compute it, e.g. by placing it explicitly (as in
"in the spec of your map") in a `delay` construct
     * choice between 1 and 2 will obviously be in the library's designer hand
* I tend to be very liberal with the use of maps inside the library
I'm writing : after all, no other code than my library will depend on
it, so I assume the choice of breaking inner parts of my lib by
exposing map keys everywhere in it. It's a kind of cost/benefit
tradeoff: no cost upfront, many benefits, and if later I have to
change more things in my lib than if I had encapsulated things, then I
both grumble and then think that the "price" of the change has been
paid several times by not having paid the cost of having encapsulated
all parts of my lib "concepts".
* I tend to be more selective with the parts of the lib which are
exposed to consumers.
  * All in all, it may not be such a big deal, because of the
following characteristic of clojure: it emphazises representing in
maps only the "essential" pieces of your domain model. Those which
will be subject to change for "good reasons" (change in spec), not
"wrong reasons" (hopefully). And, also, when it's possible, I try to
only expose as maps to consumers as little as possible. The more
"objects" they retrieve from libraries are "opaque objects" (only
intended to be passed back to library functions), the better. This is
related to the previous point: the only "objects" which remain
"transparent" are then the maps which represent the "essential" part
of the concept (only data which are not computable from other data).

HTH,

-- 
Laurent

2011/6/15 Colin Yates <colin.ya...@gmail.com>:
> Newbie so go gentle please :).
>
> I am an experienced OO Java developer (decade +) considering jumping fence
> to a functional language, and clojure is pretty high up on the list for a
> number of reasons.
>
> I am so used to defining everything as objects which are sealed units of
> state and behaviour that I am struggling to see how to solve the same
> problem with clojure.  I desperately wish somebody would write a "domain
> driven design with clojure" :).
> In brief, in OO state is exposed via a well defined API.  That state may be
> simple properties (values) or it may be calculations (functions).  And
> critically, the decision as to whether it is a value or a function is an
> implementation concern.  The Java Bean spec defines accessors for properties
> of a class, behind which lies the logic of how to retrieve that state.  So,
> the very common Person class will expose get/setName(), get/setAge() etc.
> and as a consumer I have no idea how the results are calcualted.
>
> In Clojure, if I understand correctly, the preferred way would be to use a
> map (or defstruct) with keys such as :name and :age.  These are then
> retrieved as (person :name) and (person: age) etc.
> My question is if I suddenly decided that one of those values is best
> implemented as a calculation, how can I seamlessly implement that.  By
> seamless I mean implement it without updating any consumers of a person?
>  For example, if I changed the age property to be  the result of a function,
> I could either replace the value of age with a function that calculates age
> or write a function(person)->age.
> Both of those are disruptive to the consumers of person.
> I understand that clojure is about explicitly distinguishing between state
> and functions, but I see this as a high price to pay.  Have I missed
> something?  The OO in me is saying "well, never introspect a map directly,
> rather provide get-X(person) functions" but that is very very noisy.
> That's enough for now - this is, I expect, the first of many cries for help
> :)
> Thanks in advance to all who reply!
>
> --
> 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