In Julia, I most often see code written like fun(n::T) where T<:Integer
, when the function works for all subtypes of Integer
. But sometimes, I also see fun(n::Integer)
, which some guides claim is equivalent to the above, whereas others say it's less efficient because Julia doesn't specialize on the specific subtype unless the subtype T is explicitly referred to.
The latter form is obviously more convenient, and I'd like to be able to use that if possible, but are the two forms equivalent? If not, what are the practicaly differences between them?
Yes Bogumił Kamiński is correct in his comment: f(n::T) where T<:Integer
and f(n::Integer)
will behave exactly the same, with the exception the the former method will have the name T
already defined in its body. Of course, in the latter case you can just explicitly assign T = typeof(n)
and it'll be computed at compile time.
There are a few other cases where using a TypeVar like this is crucially important, though, and it's probably worth calling them out:
f(::Array{T}) where T<:Integer
is indeed very different from f(::Array{Integer})
. This is the common parametric invariance gotcha (docs and another SO question about it).f(::Type)
will generate just one specialization for all DataType
s. Because types are so important to Julia, the Type
type itself is special and allows parameterization like Type{Integer}
to allow you to specify just the Integer
type. You can use f(::Type{T}) where T<:Integer
to require Julia to specialize on the exact type of Type
it gets as an argument, allowing Integer
or any subtypes thereof.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With