I have myself experienced the sort of “magic” that multiple dispatch + proper generic code provides, making me forget any yearning for class inheritance or other OOP features.
I had created a type for a data structure that contains kinematic data for certain moving objects, and – besides other functions specifically designed for that type – I also defined methods that extended the sum of two of those objects (+(::MyType, ::MyType)
), their multiplication by another value (only meant to work with scalar numbers, but I didn’t specify the type of the other factor), and zero(::Type{MyType})
. And then one day I discovered that I could use some functions from DSP.jl, such that for instance I could apply a FIR filter to vectors of those objects, without having to write any line of extra code!
In practice, my type had “inherited” a property of other types of time series, of being apt to be filtered, even without any knowledge of what is happening under the hood of DSP.jl. Glorious! And I’m sure that they have also “inherited” other properties of yet unknown packages that do other algebraic operations, but I don’t need to make my type child of any new parents to achieve that.
Nevertheless, the fact of having achieved this so unexpectedly is not wholly comforting, since it makes me feel that it was kind of fortuitous, and having my programs working by happy chance is not what I really want.
More generally, I think that Julia’s capacity to provide this kind of experiences is not as appreciated as it could be, because in many cases the interface that developers should take into account to make this happen is not clear. As discussed in this older post, someone with OOP background who wants to extend the functionality of some type A
, and tries to make a composite type B
containing A
, may feel intimidated by the many methods on A
that should (seemingly) be extended, even with tools like Lazy.@forward
that would facilitate that labor.
As mentioned in that discussion, abstract types with a well-defined interface can make that easy, and help to perceive the advantages of type composition + generic code + multiple dispatch. There are some good examples mentioned there, and that’s a practice that should be encouraged and promoted.