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

Reply via email to