Regarding JavaBeans and the like, more often than not I've found that
when getters and setters do not reference fields directly, they are
contributing to a composition: as an adapter, a facade, or whatever-
you-please.  It is not quite as often that getters simply return a
calculation based on data in their own object.  With that in mind,
note that such compositions usually address the problems of
structuring a program in some new way, often at run time.  Functional
programming has lots of its own solutions for such problems.

Just for reflection:
What would you do with an existing class which had a getName() method,
when you suddenly realized you wanted getFirstName() and getLastName()
instead?  Or the reverse?
What would you do if the problem you described applied to a database
table?
What would you do if you wanted to process several unrelated classes
in a generic manner, reading data from all of them?  How about an
arbitrary number of existing, unrelated classes discovered at runtime?

Clojure does encourage programming to interfaces (and protocols), and
how much state you expose is up to you.  Consider balancing this risk
by including (for defrecords) a library of functions which achieve
your client code's most common needs regarding a record type or a set
of related types (you could probably describe this as an application
of the Pareto principle).  Try not to pepper such a library with
getter functions without good reason though.  The problem you pose is
a real risk when data can be directly accessed, there is no avoiding
that; every programming language has its trade-offs, just as every
design pattern does.

Here are a few of what I've found to be the most useful pieces of
information for appreciating Clojure's functional style, coming from
OO.  The first two, at least, you've probably found already. ;)

Directly related to your question, a clojure.org page that discusses
the disadvantages of information hiding: http://clojure.org/datatypes

"Object Orientation is overrated": http://clojure.org/rationale

Stuart Halloway's Protocols and OO presentation
(ClojureProtocolsJAOO.pdf), available from
http://github.com/stuarthalloway/clojure-presentations/downloads

Out of the Tar Pit, a 60 page essay on "functional/relational
programming".  Not a light read, but convincing.  -
http://web.mac.com/ben_moseley/frp/frp.html

Ryan


On Jun 15, 2:41 pm, Colin Yates <colin.ya...@gmail.com> wrote:
> 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

Reply via email to