On Dec 11, 4:14 pm, Jason Wolfe <jawo...@berkeley.edu> wrote:
> I've been trying out the new branch, and on the whole I like it a lot.
>  I know it'll take some time to learn how do things properly the "new"
> way, and I've figured out how to do most of the things I want to do
> thus far.  Thanks, Rich!
>
> One thing I haven't figured out how to do cleanly without inheritance
> is to specify "properties" of objects in a hierarchical domain in a
> clean, efficient way.  I'm sure I haven't fully wrapped my head around
> the new abstractions, so I'd love to hear about a clean way to solve
> this problem.
>
> A very simple example is: I have a protocol "A", and sub-protocols
> "A1" and "A2".  Every A is either an A1 or A2, but not both (and this
> split is closed, as far as I'm concerned).  Sometimes I want to deal
> with instances of A1 and A2 together, and so I put the methods shared
> between all "As" in protocol "A".  But, at some point I need to
> separate out the "A1"s from the "A2"s.  To do this, it seems like I
> have at least three options:
>
> 1.  Add an "is-A1" method to Protocol A.  The problem with this option
> is that every type that derives from A1 needs to manually write out
> this method returning "true", and vice-versa for implementers of A2.
> Users could eliminate this by "extending" their types with a mixin map
> to A, rather than implementing it directly in the deftype.  But, this
> sacrifices readability (IMO) as well as efficiency.
>
> 2.  use (satisfies? A1 x) to determine if x satisfies A1.  The main
> problem with this, at least currently, is that satisfies? seems to be
> really slow in the negative case.  I profiled my (non-trivial) program
> and half the runtime was going to reflection in satisfies?  Moreover,
> this solution is not as general.
>
> 3.  Use a multimethod.  This would work generally and be reasonably
> efficient, but I feel like I'd be cluttering up my interface by mixing
> up protocols and multimethods.  On the other hand, I guess
> multimethods are the main (only?) hierarchical construct built into
> Clojure, so maybe this is what's intended.
>
> So, which do people feel is preferred?  Or have I missed a better
> option?
>
> Thanks!
> Jason

If I understand Rich's reasoning, what you want runs antithetical to
the protocols design, namely it being explicitly non-hierarchical.

As such, you'd instead have 3 composable protocols, A, B, and C (where
B and C would correspond to the functions of A1 and A2, respectively):

(defprotocol A (a [x]))
(defprotocol B (b [x]))
(defprotocol C (c [x]))

And then the type would reify the appropriate protocols:

(deftype A1 [] A B
  (a [] (println "in A1.a"))
  (b [] (println "in A1.b")))

(deftype A2 [] A C
  (a [] (println "in A2.a"))
  (c [] (println "in A2.c")))


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