Reputation: 19132
Usually one wants to define their types strict and while leaving loose type restrictions on methods (since the latter will automatically specialize, so there's no performance gain). Thus I know that for defining functions, using ::Base.Callable
is good practice. However, what about when storing functions inside of types?
In v0.5, Function
and Base.Callable
are both abstract types, and so the type
type TestType
f::Base.Callable # or ::Function
end
will not be strictly typed. One could strictly type this by using
type TestType{T<:Base.Callable}
f::T
end
which will then produce a different type for every function.
What are the benefits and drawbacks to the different approaches? It seems like the second method would cause any g(t::TestType)
to recompile for every input function, while the first method will not have the f
strictly typed. So would the second be better if you want to inline the functions (and these types are "pretty much constant"), and the first be better if you'll be changing the functions a lot? Or am I way overthinking this?
Upvotes: 3
Views: 94
Reputation: 12051
Personally when I'm on the fence, I prefer the parameterized version because it's more general. It's simple to do TestType{Any}
or TestType{Function}
if you have parameterized types, and these types will behave exactly like the unparameterized TestType
.
For instance, Base
has Vector{T}
which can be used for both specific cases like Vector{Any}
and special cases like Vector{Int}
, and in a similar vein you could have TestType{T}
which could be useful for both TestType{Any}
or TestType{typeof(sin)}
.
Upvotes: 4