
A polyglot's guide to multiple dispatch – part 2 - nikbackm
http://eli.thegreenplace.net/2016/a-polyglots-guide-to-multiple-dispatch-part-2/
======
gajomi
It a bit funny that the article doesn't mention Julia, which has native
multimethods with all kinds of bells and whistles. It could be a nice addition
to a "polyglot" flavored discussion. There is also Clojure, although its
mechanism for multiple dispatch is a bit overpowered (you dispatch on values
returned from a function of the arguments).

~~~
eliben
Part 3 will talk about Common Lisp / CLOS which had multiple dispatch 20 years
before Julia was conceived :-)

Part 4 will talk about Clojure.

I just couldn't put it all in one piece - even broken to chunks it's of
formidable length

~~~
StefanKarpinski
Common Lisp has certainly had multiple dispatch for a long time. One important
distinction, however, is that in CL generic functions are opt-in rather than
the default. This means that most operations are not generic, limiting the
extent to which you can extend things – basically only when some library
author decided that you should be allowed to. Dylan and Julia both have
functions which are generic by default, meaning that almost all functions can
be extended.

Another distinction is that while Common Lisp and Julia both have parametric
types, in CL you cannot use multiple dispatch on parametric types. Since
parametric types are a very useful for writing generic, reusable libraries,
not being able to dispatch on them is a significant limitation.

There's also the issue of performance. In Julia even something as basic as
mixed-type addition – e.g. `1 + 2.5` – is defined in terms of layers of
generic functions, but the compiler is clever enough to boil it down to a
couple of machine instructions. This allows multiple dispatch to be used
everywhere, which is really transformative. I'm not aware of any CL
implementation which can eliminate the abstraction overhead of multimethods so
completely.

It seems a bit remiss to have a series on multiple dispatch and never mention
the two languages – Dylan and Julia – that take the paradigm the furthest and
most seriously.

~~~
raiph
> Dylan and Julia both have functions which are generic by default

And Perl 6.

> in CL you cannot use multiple dispatch on parametric types.

You can in Perl 6.

> In Julia even something as basic as mixed-type addition – e.g. `1 + 2.5` –
> is defined in terms of layers of generic functions, but the compiler is
> clever enough to boil it down to a couple of machine instructions. This
> allows multiple dispatch to be used everywhere, which is really
> transformative.

MD has been used everywhere in Perl 6.

Perl 6 has maturity issues, including performance. But I see these as
temporary issues.

> It seems a bit remiss to have a series on multiple dispatch and never
> mention the two languages – Dylan and Julia – that take the paradigm the
> furthest and most seriously.

Are you omitting Perl 6 because you don't think it's ready for prime time or
you don't know enough about it's MD features?

\------

I note that the OP series is about "runtime subtype-based polymorphism". I'm
surprised at the exclusion of compile-time MD in a series which purports to be
a general guide.

~~~
StefanKarpinski
> Are you omitting Perl 6 because you don't think it's ready for prime time or
> you don't know enough about it's MD features?

Both. Are basic operations like `+` generic in Perl 6?

~~~
raiph
> Are basic operations like `+` generic in Perl 6?

Yes.

~~~
StefanKarpinski
Well, that's cool. Maybe Perl 6 will be the next good example of a multiple
dispatch language.

~~~
raiph
I think I misunderstood your comment about CL vs Julia/Dylan in regard to
generic "by default".

In Perl 6 this function definition implies a generic function:

    
    
        multi concatenate (\foo, \bar) { foo ~ bar }
    

This function definition does not:

    
    
        sub concatenate (\foo, \bar) { foo ~ bar }
    

If one views the latter as the "default" (because it's two characters shorter
and might be learned first) then Perl 6 has the same weakness, or at least the
same default, as CL, compared to Julia and Dylan.

------
phunge
Ooh Python! Check out
[https://github.com/mrocklin/multipledispatch](https://github.com/mrocklin/multipledispatch)
which is a little more fleshed out than Guido's implementation. From the
author of toolz and dask so you know it's good ;)

I also find that multiple dispatch is something that's occasionally handy, but
single dispatch is truly everywhere. I think if you broke down
multipledispatch uses in languages which embrace it (e.g. CLOS), the mix is
like 95% single, 5% >single. For single dispatch in python, check out
[https://docs.python.org/3/library/functools.html#functools.s...](https://docs.python.org/3/library/functools.html#functools.singledispatch)
which was added in to the Python 3.4 stdlib. The alternative is the OOP
subclassing style, which works but IMHO isn't very readable.

~~~
raiph
MD in Perl 6 is beyond "occasionally handy". A glance at the Perl 6 setting
modules[1] revealed something like a 50/50 break down of SD vs MD.

Operators in Perl 6 are all MD, so that's likely a significant factor.

Additionally it is well designed. While the functionality starting point was
CLOS, the UX has the benefit of hindsight and a decade of non-stop language
evolution.

[1]
[https://github.com/rakudo/rakudo/tree/nom/src/core](https://github.com/rakudo/rakudo/tree/nom/src/core)

------
ThatGeoGuy
Although a bit less interesting than part 1 IMO, I think it's still a really
good read, especially the point:

    
    
        However, as we've seen here there are several variations
        on the multiple dispatch scheme, and each requires
        slightly different implementation considerations.
    

This is interesting, and probably pretty important, especially if you're
considering using Multiple Dispatch (MD) in a code base yourself. One of the
advantages of CLOS-style MD is that it is built in, and usually covers your MD
needs for 99%+ of cases (from what I've seen, at least). Looking forward to
part 3 next week Eli!

------
StefanKarpinski
part 1:
[https://news.ycombinator.com/item?id=11526923](https://news.ycombinator.com/item?id=11526923)

------
Diederich
Is this an example of what Mr. Bendersky is talking about? I believe so:

[https://github.com/perl6/book/blob/master/src/multi-
dispatch...](https://github.com/perl6/book/blob/master/src/multi-dispatch.pod)

~~~
Someone
No. That is overloading with single dispatch. You need multiple arguments for
multiple dispatch (they can be implicit, as with the 'this' argument in C++,
but they rarely, if ever, are because making one argument implicit makes it
look as if the situation is asymmetric in the arguments, and that is exactly
something multiple dispatch is not)

Edit: oops. I didn't notice that the discussion went beyond the _to-json_
example, which definitely is _not_ multiple dispatch. The discussion starting
at the header _Multiple arguments_ is about multiple dispatch.

~~~
arnsholt
Perl 6 dispatches on multiple arguments based on runtime types, so it's full
multiple dispatch.

~~~
raiph
I thought that, while Perl 6 _can_ dispatch based on runtime types, it does
candidate resolution at compile-time for functions (and thus operators) and
private methods. It only adds in run-time overhead for these cases if the code
uses a run-time type construct. Am I wrong?

