On May 22, 2012 7:09 AM, "Softaddicts" <lprefonta...@softaddicts.ca> wrote: > 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.
I really don't understand your example. Personable#age conflicts with CensusOperators#age if you define them in the same Namespace (and you'll get a warning telling you so) . If they're in separate namespaces , what's the point of Personable #age, given you never define an implementation? > 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 -- 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