On Thu, Jan 2, 2014 at 10:01 AM, Mauro <[email protected]> wrote:
> Only abstract types can be subtyped (and if I recall correctly this
> is going to stay that way for some type-theory-reason).
>
It's not for a type theory reason – if anything, it's the opposite of a
type theory reason. If Float64 can be subtyped, then then an Array{Float64}
can hold objects of arbitrary size. Thus, you can't represent it as inline
data, but rather have to store the array as pointers to boxed,
heap-allocated values. Not only is this horribly inefficient (200% storage
overhead on 64-bit machines), but it completely destroys interoperability
with BLAS, FFTW, etc.
Some o.o. languages have allowed declaring types to be "final" as a way of
dealing with this issue (you also need immutability and/or value types to
fully solve the array storage problem). After a few decades of real-world
o.o. programming, however, the best practice that's emerged is that you
should only subtype intentional supertypes – types that are very carefully
designed to be subtypeable. Where a classically o.o. language might do Ac
:> Bc, where Ac and Bc are both concrete and Ac is a supertype of Bc, in
Julia you would have Aj' :> Aj, Bj where the abstract aspect of Ac is
distilled into the purely abstract type, Aj', while the concrete aspect of
Ac is implemented by Aj, which is a sibling of Bj instead of its parent.
I've found that while this requires a slight shift in thinking, the
resulting designs tend to be much better: the abstract behavioral aspect of
Aj' is completely separated from any implementation concerns since you're
not allowed to mix them.