Problems with dispatching of Base.iterate

The situation is the following: I’m defining some iterators with the following structure

module foo

module Generic
import Base: iterate

abstract type Gen

struct iterator{G} where {G<:Gen}

Base.iterate(S::iterator{Gen}, state) = ...


module Specific
using ..Generic
import Base:iterate

struct Spec<:Gen

Base.iterate(S::iterator{Spec}, state)=...

But the compiler seems like it cannot find Base.iterate(S::iterator{Spec}, state), i.e., it tries to dispatch on the Generic method and not on the Specific.

Do you have any clues?

Best wishes

I solved it, I will leave it here so if anyone has the same problem, there is an answer.
The main clue is that, if we have an

abstract type A 

I was dispatching as


which is different than

f(x::T) where {T<:A}

so the dispatcher could not find the right method.

Best wishes

It’s not different–those method definitions are exactly the same:

julia> abstract type A end

julia> f(x::A) = 1
f (generic function with 1 method)

julia> f(x::T) where {T <: A} = 2
f (generic function with 1 method)

Note how f still has exactly one method, because A and T where T <: A are exactly identical:

julia> (T where T <: A) === A

Reading between the lines in your example, I wonder if you were actually doing something like:

julia> struct Container{T}; end

julia> g(x::Container{A}) = 1
g (generic function with 1 method)


julia> g(x::Container{T}) where {T <: A} = 2
g (generic function with 2 methods)

Because parametric types in Julia are not covariant, Container{A} and Container{T} where {T <: A} are indeed different.

This comes up often in arrays, since an Array{Real} is an array in which each element can be any (different) kind of Real, while an Array{T} where {T <: Real} is an array with an element type which is itself some subtype of Real. Thus, Array{Int} is a subtype of Array{T} where {T <: Real}, but Array{Int} is not a subtype of Array{Real}. Invariance can be hard to wrap your head around the first time–I had to read this section of the manual a few times before I got it:

1 Like

Yes, you’re right, it was a parametric type! I missed the huge yellow warning in the page you linked… Thank you for the nice answer, it cleared up things.