I don’t think there are rigid rules for every situation. I think of the type system as a set of building blocks, which I can use to design solutions that fit the problem well. I usually try to adhere to the following:
- abstract types are good for designating interfaces, you can also make a hierarchy of them, keeping substitutability in mind,
- slots should not be part of the interface, introduce accessor functions, even if trivial,
- composition is useful and convenient, just forward methods (some macros make this more convenient, eg
Lazy.@forward
).
For a pretty polished and well-maintained example, look at
which is similar to your problem: OffsetArray
s contain arrays, yet they are also arrays, extending functionality.