OOP-brained design patterns

This is an interesting pattern which leads to very efficient code. However, the readability is not so great.

What I use in these cases:

  • Always introduce an abstract type per concrete type, at least for types which are public. For MyType this would be AMyType (because it is a MyType in the sense of “I don’t care which one” – interestingly, this implies the same meaning as AbstractMyType or AnyMyType, but is shorter and simpler to read after getting used to)
  • Use the concrete type in the field constraints of your structs (obviously).
  • Never type-constraint your methods to the concrete type, but to the abstract type.
  • If you want to extend a type, it’s then simply introducing another abstract type (to again be reusable) and letting a macro from one of the packages copy over the fields into a new type.

No downsides of this procedure have been identified when I asked here.
One day I should probably create a package for this so that you could e.g. write

@extendable struct Base
    baseField::Int
end

function do_something(base::ABase)
    base.baseField
end

and it would just work. Or even better

using ExtendableModules

@extendable module MyModule
struct Base
    baseField::Int
end

function do_something(base::Base)
    base.baseField
end
end

where the macro would rewrite all structs in the module to define their abstract type, too. Additionally, it would rewrite all method type constraints to use the abstract types. That would be nice.