On Mon, Jan 7, 2013 at 6:01 AM, kovas boguta <
kovas....@gmail.com> wrote:
> Got it. Just asked because the examples happend to be all about the
> first argument.
>
> dnolen had looked into related issues in some depth, but I can't find
> the threads now.
>
> I like the idea. I presume this also applies for anonymous functions?
>
> I would also be in favor of dispatching on keywords (or arbitrary
> values for that matter), and on structural features like
> (defn foo
> ([a [b]] "case 1")
> ([a [b c]] "case 2"))
>
> The spirit of the idea is to dispatch on "what kind of thing it is",
> and it would be a shame if the only measure of our things is what type
> they are.
>
> Its also worth looking at what Julia has done wrt multiple dispatch:
>
http://www.infoq.com/presentations/Julia
If I understand correctly, what Mike is describing is static dispatch,
and that is the major difference between what he is describing and
multimethods and protocols. What would happen is Clojure would
generate a class that implements IFn (which has only Object typed
arguments) *and* some 'invoke' methods that have specialized types. If
the compiler knows the type signatures of the arities of the function
being called and the types of the arguments, then it can generate
bytecode that would directly invoke the specialized invoke methods. If
it does not know the types of the arguments, then it would generate
code to call the Object invoke method. The body of the Object invoke
method would be a cond that either invokes the appropriate specialized
invoke method, or throws an exception.
I don't know how well this idea could be extended to other features.
Any feature would have to be knowable at compile time, and also
encodable as a Java method either with types (which is directly
supported by Java) or with name munging or something.
One drawback I see with this is that it is very concrete. Protocols
work against interfaces which allow multiple implementations. The IFn
interface allows only Object typed methods. Since they are not part of
any interface, these specialized methods are specific not only to the
static types of the arguments, but also the function that you are
compiling. Any high order functions would be unable to take advantage
of these specialized methods, because the compiler would only see them
as IFn instances. You could possiblly pass some additional type
information to a high order function, but it would tie itself directly
to the concrete class of the function with specialized methods, since
interfaces are the way to abstract away from concrete instances, and
again these specialized methods are not part of any interface.
The other way to abstract away from concrete classes is to take
advantage of invokedynamic. With invokedynamic you can compile an
invocation of a method with a specialized type signature that is not
tied to a concrete class, and at run time you link that type signature
to a specific class. invokedynamic may be faster than the current way
to do this (Mike's original example of a cond dispatching on type),
but it probably won't be faster than invoking through an interface, at
least not yet. It also would require Java 7.
I've had similar thoughts to Mike, but it was in the context of "how
would I implement Clojure differently knowing I can use
invokedynamic?" and I would probably do something like this where you
get rid of the IFn interface and just dispatch to a method named
'invoke'. You could encode as much type information as you know at
compile time into the invocation, and link it at runtime, either
calling a specialized method or an Object typed method.
Paul