Interesting project, although I'm still a little unclear about the "convincing" 
use cases where you would choose polyfn over protocols...

Also, how does the polyfn implementation compare to the clojurescript protocol 
implementation?

-FrankS.


On Oct 8, 2012, at 7:17 PM, Paul Stadig <p...@stadig.name> wrote:

> On Monday, October 8, 2012 1:55:50 PM UTC-4, Tassilo Horn wrote:
> Paul Stadig <pa...@stadig.name> writes: 
> 
> Hi Paul, 
> 
> > I created a library for Clojure to do open, single dispatch 
> > polymorphism. What does this mean? 
> > 
> > * A polyfn dispatches on the type of its first argument. 
> > * You can add an implementation for a new type to an existing polyfn. 
> > * You can define a new polyfn on an existing type. 
> > 
> > Polyfns are exactly as fast as protocol functions (I am using the same 
> > caching and dispatch code), but they do not generate a Java interface, 
> > and they are slightly simpler to define. 
> 
> Sounds cool. 
> 
> I have a bunch of mostly one-method-protocols that I extend upon 
> existing (95% java) types.  I don't rely on the existence of the 
> protocol interfaces, and neither do I use extends?, satisfies?, or 
> extenders. 
> 
> Would it make sense to switch to polyfns?  Are there more advantages 
> except from the definitions being slightly more concise?
> 
> I can't say that you should necessarily switch to polyfns, but this was the 
> kind of situation I was imagining. polyfns are the fast and open type based 
> dispatch decomplected from protocols, and I think that's the main advantage, 
> simplicity.
> 
> A drawback with polyfns is there's no Java interface that can be extended in 
> Java code to participate in the dispatch. The Java interface is nice, but as 
> you mention below, the generation of interfaces can cause staleness issues 
> especially when paired with defrecord. defprotocol and defrecord both 
> generate a new class each time you compile them, because of the way classes, 
> class loaders, and class identity work.
> 
> Another difference between protocols and polyfns is that everytime you 
> compile a defprotocol form it regenerates the protocol functions, whereas a 
> polyfn is generated once and never changes (only the dispatch table changes). 
> This has implications though I'm not sure how much they matter. YMMV
> 
> One minor problem I have with the protocol approach is that if you 
> recompile a protocol during interactive development, then calling the 
> protocol methods on already existing instances in your repl session of 
> types on which the protocol has been extended won't work anymore.  Do 
> polyfns help there? 
> 
> defrecord will behave differently depending on how you extend the protocol. 
> If you extend the protocol inline in the defrecord form, then the class that 
> defrecord generates will implement the protocol interface. In this case 
> nothing gets added to the protocol dispatch  table, and instead dispatch 
> happens through the Java interface. When you recompile the defprotocol form, 
> it regenerates the Java interface and the protocol functions. The new 
> functions it generates know only about the new interface, so they complain 
> when you give it an instance of your defrecord that you had stashed away 
> before you recompiled.
> 
> If you define a defrecord and extend a protocol to it using extend-protocol 
> or extend-type it adds an entry to the dispatch table for the protocol. Since 
> dispatch happens through the dispatch table instead of the interface, then 
> when you recompile your defprotocol and defrecord your old instances continue 
> to work, but because of the way class identity works they continue to 
> dispatch to the implementation of the protocol that was defined when you 
> created your instance. In order to invoke the new implementation of the 
> protocol, you need to create a new instance of your defrecord. Every time you 
> recompile your defrecord it adds a new entry to the protocol's dispatch 
> table, so the table will contain a number of entries on the order of the 
> number of times you have recompiled your defrecord.
> 
> Since polyfns do not generate a Java interface through which they dispatch, 
> they will behave like this second case. Your old instances will continue to 
> work, but with the polyfn  implementation that was associated with the 
> instance's class, and your dispatch table size will be on the order of the 
> number of times you have recompiled the polyfn forms.
> 
> I'm not sure if this is better or worse than what happens in the first case, 
> but I do know that in 100% of the cases where I've used protocols I have not 
> really needed the Java interface. Though it also doesn't really hurt anything 
> to have the interface around if you're not using it.
> 
> -- 
> 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

Reply via email to