Paul Stadig <p...@stadig.name> writes:

Hi Paul,

thanks for the detailed answer.

> A drawback with polyfns is there's no Java interface that can be
> extended in Java code to participate in the dispatch.

At least currently I don't see a use-case where I'd need to do that.

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

I never dug very deep into this problem, but now where you mentioning it
I can confirm that this problem occured always with deftype instances
that where extended with several protocols inline.  As a consequence,
I've moved the protocols and deftypes into a separate namespace which I
usually don't need to recompile since those definitions are rather
stable.  The downside is that now I have namespaces with a meaning plus
several purely technical sub-namespaces.

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

Ah, so if I change a polyfn for a type X, the new behavior will only be
available to new X instances, right?

Well, as said, those are pretty stable, so it's no issue for me.  How
about the growth of the dispatch table?  Say, I recompile a namespace
containing polyfn definitions 50 times during a session, will that slow
down dispatch noticeably?  Maybe you could store the current active
definition form per type, so that identical definitions for the same
type don't get added to the dispatch table?

Oh, and here's a whishlist item: It should be possible to add a
docstring to polyfns, and maybe also other metadata (:pre, :post, :tag,
...).  tools.macro/name-with-attributes makes that pretty easy.

And another question: Since defpolyfn expands into a defonce form, does
that mean that all (defpolyfn foo ...) forms have to be in the same
namespace?  It looks to me that currently defining the same polyfn foo
in different namespaces bar and baz will create bar/foo and baz/foo
which have nothing to do with each other (you cannot `use` both bar and
baz).  IMO, that would be an argument for splitting polyfns into a
single declaration form and many definition forms providing
implementations for several types (like defmulti and defmethod, or
defprotocol and extend).

Bye,
Tassilo

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