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