I've been wondering about this topic recently as well. >Often such a function does not need to be part of the contract for >implementers (i.e. the protocol) at all.
Stu, (or anybody) I'd like to ask about a variation on this point. How do you handle the case where you have a general function that works for every type you'd like to implement a protocol for (thus not technically needing to be in a protocol), but maybe 1 or 2 of the many types have more efficient implementations possible? Do you just suck it up and copy and paste the general function around? Or is there a better way? Maybe the new case function? After reading the docs on clojure.org/protocols, it seemed like you could just define the general implementation of functions under Object and then define your specific implementations on the other types, but this didn't seem to work for me. I would get an error to the effect of "foo is not defined for Type" On Aug 12, 9:51 am, Stuart Halloway <stuart.hallo...@gmail.com> wrote: > The other thing that you should consider is that protocols are the contract > for implementers, not the contract for callers. If you change a contract for > implementers, then the implementers *must* change. > > Take your example of a function that has a reasonable default for any object. > Often such a function does not need to be part of the contract for > implementers (i.e. the protocol) at all. > > To make this more concrete, look at how protocols are used in Clojure itself. > InternalReduce is a contract for implementers, consumers call reduce. Ditto > for IOFactory: clients don't call it, they call the functions reader, writer, > etc. instead. > > Stu > > > > > Does this > > help?:http://fulldisclojure.blogspot.com/2010/08/thoughts-on-protocols.html > > > And Sean's comment > > here:http://programming-puzzler.blogspot.com/2010/08/racket-vs-clojure.html > > > Regards, > > Shantanu > > > On Aug 12, 5:46 pm, Laurent PETIT <laurent.pe...@gmail.com> wrote: > >> Hi, > > >> 2010/8/12 Matthew <mattp...@gmail.com> > > >>> Hello all, > > >>> I've been looking at the new protocol (defprotocol, deftype, > >>> defrecord, etc) feature in 1.2 and, while I love the core concepts, > >>> it's been bothering me that there's no apparent way to provide > >>> *automatic* default implementations for methods on a protocol. > > >>> I know from reading Rich Hickey's discussions on the design rationale > >>> [1] and other threads on providing Scala Trait-like behaviour [2] that > >>> you can choose to mix in a set of defaults when you implement the > >>> protocol, but it seems important to me that a protocol author be able > >>> to provide default implementations to enable protocols to evolve. > >>> Allowing a function body in the defprotocol clause would seem to be > >>> the obvious way, something like: > > >>> (defprotocol P > >>> (foo [x] (default-foo x)) > >>> (bar-me [x] (bar-me [1 x]) > >>> [x y])) ; no default implementation > > >>> As I'm sure most of you know, a key problem with "pure" interface > >>> features in environments like CORBA, COM, Java, etc has been that you > >>> can't add new methods to published interfaces: you'd break all > >>> existing implementations. Hence you see a history of evolving > >>> interfaces indicated by names like IFoo, IFoo2, IFooEx, etc. In > >>> contrast, a Scala-like trait system allows you to add a new method > >>> *and* a default implementation (supposing that makes sense), so old > >>> clients still work fine. > > >>> The problem, as I see it, with Clojure protocols is that you would > >>> have to rely on clients mixing in a set of defaults in order to > >>> happily extend a "public" protocol. > > >>> Am I missing something key here? I realise there are some very > >>> experienced people contributing to Clojure, so am fully expecting to > >>> be told I've missed something obvious ;) > > >> Maybe have the library writer do this ? : > > >> (defprotocol P > >> (foo [x] (default-foo x)) > >> (bar-me [x] (bar-me [1 x]) > >> [x y])) ; no default implementation > > >> (def *P-defaults* > >> {:foo default-foo > >> :bar-me #(bar-me 1 %) }) > > >> and let the user pick the whole *P-defaults* for its mixins, or just parts > >> of it ? (does this make sense ?) > > >>> Cheers, > > >>> Matthew. > > >>> [1]http://groups.google.com/group/clojure/msg/330c230e8dc857a9 > >>> [2]http://groups.google.com/group/clojure/msg/53228e04db4799a5 > > >>> -- > >>> 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<clojure%2bunsubscr...@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 -- 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