Thank you Stuart. All the years of thinking about functions as being subservient to objects has warped my brain. I believe I've read about this inversion for protocols before but I don't think I've really grasped all the consequences of it until now.
What I'm taking away from this is that it is probably best practice to have protocols in a separate namespace from any implementations to avoid confusion when I recompile an implementation (file). On Aug 26, 12:36 pm, Stuart Halloway <stuart.hallo...@gmail.com> wrote: > The problem here is that you are presuming that a protocol function "bar" is > a behavior of the types it is extended to. Invert that: "bar" is its own > function, and the types come to it, not the other way around. If you > explicitly replace "bar" with a new function (which redeclaring the protocol > does), then call the new function, you will get ... the new function. > > Types don't have behaviors. Behaviors have (a dynamic association with) > types. The fact that you can declare the behavior inline on a type is a > convenience: The controlling entity is the function, not the type. > > There is a real practical issue here, but it is more modest than what you > describe. You can add a new default implementation anytime you want, without > causing any problems with existing implementations. It is redefining the > *protocol* that causes a need to revisit other code. Tools could indeed help > with this. > > I realize that this is unfamiliar for people (including myself) coming from > OO, but I want to emphasize that your confusion is not about an ancillary > point -- it is central to how protocols work. > > Hope this helps, > Stu > > Stuart Halloway > Clojure/corehttp://clojure.com > > > > > Perhaps I should have explained why I think 20 should be the right > > answer. > > > This is based on my expectation that once I've compiled a file the > > behavior of records or types defined in that file will not change > > (unless I re-bind functions called by the record or type). The above > > behavior violates this principle in a very natural use case where I > > add or recompile a default implementation of a protocol located in a > > separate file from a record implementing that protocol. > > > On a more practical level the current behavior means I have to > > explicitly recompile multiple files when I change a line in one file, > > which is somewhat inconvenient (perhaps there should be a way to auto- > > detect this situation and have the Clojure compiler recompile the > > appropriate file???). If I forget to do this then the code will behave > > in unpredictable ways because I've suddenly replaced the non-default > > implementations with a new default implementation. > > > On Aug 26, 7:08 am, MikeM <michael.messini...@invista.com> wrote: > >> I may have misunderstood what I've read about protocols, so please set > >> me straight if the following is wrong - > > >> On Aug 25, 11:08 pm, Stuart Halloway <stuart.hallo...@gmail.com> > >> wrote:> I think the current behavior follows the principle of least > >> surprise: > > >>> (1) bar is a function, in whatever namespace the protocol Foo is defined > >>> in > > >> But bar is not a single function. Multiple bars can coexist in some > >> sense, right? Otherwise there's no polymorphism? > > >>> (2) you redefine bar (perhaps by reloading the file Foo is in) > > >> I don't see this as bar being re-defined, rather bar is defined for > >> fooed, then defined for Object > > >>> (3) you call bar and get the new behavior > > >> It seems that the dispatch mechanism for bar is preferring Object's > >> bar rather than user.fooed's bar. This is not what I expected. So > >> maybe the right way to think about this is that protocols don't pay > >> attention to class hierarchy when dispatching: user.fooed is an > >> Object, and bar was defined for Object after bar was defined for > >> user.fooed, so Object's bar is selected? > > > -- > > 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