To be clear, when I write “multiple inheritance” in this context, I don’t mean multiple structural inheritance (as in C++), but rather multiple abstract class inheritance. In other words, the allowance for a node in the type graph to have multiple parents.
With its current limitation of a type tree, Julia can’t express (at the type level) some of the broader commonalities between objects. Iterability, for instance, has no abstract type, and so the tightest type bound for something that might be iterable is just
Any. This in turn limits the granularity at which non-ambiguous methods can be defined, since a definition of
foo() on all iterable things would have to be
Obviously, allowing a type to inherit from multiple abstract types would add many more potential sites for method ambiguity, but is that actually what’s stopping this feature from existing? Or are there deeper technical implications or design considerations I’m unaware of?
Is inheritance even a thing for Julia? Thought Julia is more like Go at best. Composition and embedding only. No inheritance from OO.
With Julia, you can simulate multiple inheritance using “Holy Traits”. See here: https://github.com/JuliaLang/julia/issues/2345#issuecomment-54537633 for the original description. See here: https://github.com/mauro3/SimpleTraits.jl for a package including macros to generate them automatically.
This has certainly been discussed as a possibility. I think Jeff Bezanson might have mentioned this in a talk in JuliaCon 2017 (possibly this talk - https://www.youtube.com/watch?v=Z2LtJUe1q8c).
It’s taken a fair bit of effort to get a typing system with an accurate subtyping algorithm that combines
- An (abstract) single-inheretence tree
- Invariant type parameters (either types with upper/lower type bounds, or constant values)
- Covariant tuple type parameters (we happen to allow values here too)
- Tuples of variable numbers of arguments (
For a view into the complexity required to achieve all this, see this JuliaCon 2018 talk: https://www.youtube.com/watch?v=Y95fAipREHQ
My observations are that we’re at the stage where the language has been moving fast and we’d possibly like to consilidate a little before considering major changes to the type system. The open questions here are whether we move towards multiple inheretince, interfaces, traits, etc - and what are the design/implementation tradeoffs of each of these?
For the moment, as mentioned, using traits in an explicit manner (“Tim Holy traits”) lets you handle basically any type “inheretence” model you could possibly want (as far as I can tell, anyway).
I would like to add that this is a broader issue that not only includes multiple inheritance but additionally there is the desire to define
interfaces for abstract abstract types. There has been long discussions on Github, see for instance:
There was some discussions whether these interfaces (later called protocols) should be connected to the abstract type hierarchy or whether they should be disconnected. The later had the advantage that a type can fulfill an interface even if it has not been declared upfront.
That issue seems to have been added to a
2+ milestone at some point, but that one was deleted - are there plans for putting this into the correct
2.0+ milestone or has it been postponed further?
The 2.0 release hasn’t been planned at this point AFAIK, so the milestone doesn’t mean much. Nothing is postponed to 3.0 either – 1.0 has just been out for a few weeks!
I guess most developers may want to
- take a break (it has been a lot of hard work),
- clean up remaining issues (there are lot of them),
- get some mileage out of 1.x
before planning 2.x. It is fine to think about improvements to the language, but I would not be surprised if fundamental redesigns of the language were met with lukewarm interest for a while.
Totally fair, just noticed it while looking at the issue and thought I’d ask