The Unreasonable Effectiveness of Multiple Dispatch
2019-07-25, 11:00–11:30, Room 349

If you're familiar with Julia and its ecosystem, you may have noticed something lovely but a bit puzzling: there seems to be an unusually large amount of code reuse between packages compared to other seemingly similar languages. This sharing of code comes in two forms:

  1. Sharing basic types among a wide variety of packages providing disparate functionality;
  2. Sharing generic algorithms that work on various implementations of common abstractions.

Why does generic code in Julia "just work"? Why do Julia packages seem to share types with so little friction? Both kinds of reuse are supposed to be natural benefits of class-based object-oriented languages. After all, inheritance and encapsulation are two of the four pillars of OOP. Even more puzzling is that Julia has no encapsulation and doesn't allow inheriting from concrete types at all. Yet both kinds of code reuse are rampant. What is going on? In this talk, I make the case that both of kinds sharing stem directly from Julia's multiple dispatch programming paradigm.

The former kind of sharing of types stems from the external nature of multiple dispatch: the source of many problems in class-based OOP is that methods have to live "inside of" classes. Simply by associating methods with generic functions rather than the type that they operate on, multiple dispatch avoids many of the problems that OOP has.

The latter kind of sharing stems from the ability to correctly choose specialized code based on the types of all arguments of a function. There are patterns like double dispatch to try to deal with this in single dispatch languages, but they are cumbersome, brittle and opt-in, meaning that unless someone else planned for you to extend their code, you are unlikely to be able to do so.