Interesting demonstration, except for one thing, defining getters is a waste of
time :)

When you need to define accessors, you start to run into inefficient use of
your time. It still a bearable workload in Java because of all this heavy 
tooling that allows
to select for which fields accessors will be generated.
Without getters, you would also expose mutable stuff to the universe.

However in Clojure the values are not mutable... Why bother defining 
an accessor to a read-only value ?

A better way would be something like:

(defprotocol Personable
    (person [this])
     (age [this] )

(defprotocol CensusOperators
    (age [this]))

(extend-protocol Personable
    Person 
    (person [this] this)
    Employee
    (person [this] (:person this)))

(extend-protocol CensusOperators
     Person
     (age [this] (date-dif (java.util.Date.) (:birthday this)))))

Much more convenient to me. I can take anything and make it a person.
Even from a Clojure map just by extending it and returning a Person instance.
You expose the Person abstraction when available instead of hiding it.

Computed values like the age ? This is something that could be computed
for other entities like an animal.

So you can write (age (person xxxx)) or (age (animal xxxx)).

This is why I tell people to get out of their usual thinking process. Get lazy,
playing hide and seek was fun at pre-school age but in your code and data
structures ?

Luc P.


> I think it's misleading to use inheritance to reduce code duplication.  
> Inheritance is about indicating function typing and creating typed 
> contracts, both of which are fairly un-idiomatic in Clojure.
> 
> However, there is another way to prevent code duplication: use composition 
> instead.  Instead of having the Employee class mirror the attributes of the 
> Person (which if you really wanted, you could easily do via a "defperson" 
> like macro that would slug on extra fields), why not have an Employee carry 
> a Person as one of its attributes?  This approach is more similar to the 
> Haskell/functional way of working with record types (I think Haskell's 
> newtype operator works similarly under the covers).  There is also an 
> analogue to the decorator pattern in Java.
> 
> In this case, you would specify a Personable protocol, which both Person 
> and Employee implement; for all the basic operations, Employee would just 
> defer to its internal person.  Example:
> 
> (defrecord Person [name birthday])
> 
> (defrecord Employee [title person])
> 
> (defprotocol Personable
>   (name [this])
>   (age [this))
> 
> (extend-protocol Personable
>   Person
>   (name [this] (:name this))
>   (age [this] (date-dif (java.util.Date.) (:birthday this)) ;;date diff 
> defined elsewhere
>   Employee
>   (name [this] (name (:person this))
>   (age [this] (age (:person this)))
> 
> Arguably, if we were deferring to the current Java best practices and 
> encapsulation, one should be creating interfaces of getters and setters 
> rather than directly accessing instance variables anyway, making the extra 
> protocol definition no more work than doing it correctly in modern Java.
> 
> Best,
> Mark
> 
> On Sunday, May 20, 2012 10:22:55 AM UTC-7, Warren Lynn wrote:
> >
> > So from what I read  the philosophy of Clojure discourages inheritance 
> > on concrete data types. However, maybe I am too entrenched in my OO 
> > thinking, how do I define a new record type that includes all the data 
> > members of another record type? I am thinking about the classic 
> > Employee/Person example. 
> >
> > If I can define a record of Employee with Person's data members 
> > included, even that is not true inheritance (as no protocols of 
> > "Person" will be automatically extended to "Employee"), I need that 
> > for function re-use (so a function working on Person will 
> > automatically work on Employee because Employee is guaranteed to have 
> > all the data members in Person). 
> >
> > Also, again, maybe I am too OO minded, is there a way inherit another 
> > record type's protocol implementation? That seems to give the best 
> > combination of both worlds (OO and functional), so you can either have 
> > you own very customized combination of data type/protocols, or use the 
> > very common OO pattern. Just like we have both the single-typed 
> > dispatching (which is more OO like and covers a large portion of use 
> > cases), and more advanced multimethods. 
> >
> > Thanks.
> 
> -- 
> 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
--
Softaddicts<lprefonta...@softaddicts.ca> sent by ibisMail from my ipad!

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