I've been playing around with some code that uses abstract types as
parameter tags (think Ptr{Void}, Ptr{Int64}, etc.), and more recently
using a hierarchy of abstract tag types. The other hurdle in what I'm
trying to do is the use of external data files that need to be loaded and
used in the construction of specific tag types (i.e. a separate file for
each sub-tag type). I started out with just the regular type constructor
with a check to isdefined to see if the data had already been loaded, load
if not, otherwise use it in constructing the specific type. This felt a
little clunky and had a performance hit with the reflection, so I came up
with a possibly heretical approach.
abstract Tag
abstract MoreSpecificTag
type TagType{T:Tag}
x
end
# Fallback/Default constructor
function TagType(x,t) #where t : Tag
# External data file loaded for specific Tag type t
# Data used in processing the TagType{MoreSpecificTag} constructor
eval(:(function TagType(x,t::Type{$t})
# TagType{MoreSpecificTag} construction
# Manually inline data points, etc.
return TagType{t}(x)
end
))
return eval(:(TagType($x,$t)))
end
# 1st call dispatches to fallback
# Generates TagType{MoreSpecific} constructor, then calls it
TagType(1,MoreSpecificTag)
# 2nd call auto-dispatches to generated constructor
TagType(1,MoreSpecificTag)
Is this crazy? Potential concerns? In some light testing, it seems to all
work as expected, but I just wanted to pitch it to see if this is too hacky
or not.