Mohamed Kamal
Mohamed Kamal

Reputation: 81

Why are many different ways to dispatch with abstract types in Julia ? and what is the difference between them?

What is the essential difference between those three different ways of declaring a function with abstract type in julia ?

Base.zero(::AbstractZero) = Zero()
Base.zero(::Type{<:AbstractZero}) = Zero()
Base.zero(::Type{T}) where T <: AbstractZero = Zero()

Upvotes: 4

Views: 237

Answers (2)

Ronny
Ronny

Reputation: 144

You can also do

Base.zero(::T) where T <: AbstractZero = Zero()

similar to the first variant with the same explanation as @Bogumił Kamiński gave, that is, if you want to use the type T within your function, that actually called the function.

Upvotes: 0

Bogumił Kamiński
Bogumił Kamiński

Reputation: 69829

Base.zero(::Type{<:AbstractZero}) = Zero()

and

Base.zero(::Type{T}) where T <: AbstractZero = Zero()

are almost the same. In this case they are the same.

The difference would be if you wanted to use T in the definition of the function somewhere (as in the first case it is undefined).

To be precise:

Base.zero(::Type{<:AbstractZero}) = Zero()

expands to:

zero(::Type{var"#s1"} where var"#s1"<:AbstractZero)

but the scoping difference is neglibible.


Now the difference between:

Base.zero(::AbstractZero) = Zero()

and

Base.zero(::Type{<:AbstractZero}) = Zero()

is that the first dispatches on an object of a given type, and the second dispatches on a type itself. Here is an MWE:

julia> f(::Integer) = "integer passed"
f (generic function with 1 method)

julia> f(::Type{<:Integer}) = "integer type passed"
f (generic function with 2 methods)

julia> f(1)
"integer passed"

julia> f(Int)
"integer type passed"

Upvotes: 5

Related Questions