OP here,
So it looks like the consensus is to use a single type with un-used
features set to nothing. I've actually been playing around with this
approach since I posted this question. Here's what I've got:
abstract AbstractCar
abstract Color
abstract Year
typealias ColorOrVoid Union{Color, Void}
typealias YearOrVoid Union{Year, Void}
type Car{C<:ColorOrVoid, Y<:YearOrVoid} <: AbstractCar
color::typeMap(C)
year::typeMap(Y)
end
where the function typeMap will send Void to itself, Color to ASCIIString
and Year to Int. However I tried doing this and I got an error, I probably
the way to do this is with meta-programming and macros, but I'm not sure
how since I'm a complete novice at meta-programming.
I would also like to have outer constructors which allow me to avoid having
to enter Void for all the un-used features, so if I'm only interested in
Year, I would have an outer constructor of the form:
Car{Year}(y::Int) = Car{Void, Year}(nothing, y)
However this gives me an error saying that *static parameter Year does not
occur in signature for call at none*.
On Thursday, April 14, 2016 at 10:08:53 PM UTC-7, Toivo Henningsson wrote:
>
> As you say, it's a lot of types. If you would really need to instantiate
> an exponential number of types then maybe you should reconsider, because
> the jit compiler has to do quite a lot of work for each type that is used.
>
> But if you're not actually going to instantiate such a humongous number of
> them, or if you really want to be able to use specialization and dispatch
> in this way: How about a middle road where you use a parametric type and
> set the types of all unused fields to Void (the type of nothing)? That
> should be able to support the cases that you mentioned.
>
> Also, in many cases, storage for a value worth known type of eg Void is
> free, since it is known that there is only one instance. The exception is
> if the value could be uninitialized as well.
>
>