Chris Rackauckas
Chris Rackauckas

Reputation: 19132

Storing Functions inside of Types

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

Answers (1)

Fengyang Wang
Fengyang Wang

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

Related Questions