How to dispatch on an iterable (e.g. accept both tuple or array)

Is it possible to dispatch on if a method argument is iterable? I’d like to dispatch a method based on if an argument is scalar input or some kind of iterable. My main target for the iterable method is to accept either an Array or a Tuple. Is that possible? Or do I need to use traits for this?

Looks like some discussion on this already occurred:

And SimpleTraits has an IsIterator trait

The SimpleTraits.jl solution fails because numbers are iterable:

using SimpleTraits
using SimpleTraits.BaseTraits

@traitfn f(x::T) where {T; IsIterator{T}} = "iterable"
@traitfn f(x::T) where {T; !IsIterator{T}} = "not iterable"

I get

julia> f((1,2))

julia> f([1,2])

julia> struct A

julia> f(A)
"not iterable"

which looks great, but then

julia> f(1.0)

I don’t think this is feasible. In a lot of code foo(itr::Any) is the “Any” method, so iteration is the default and then <: Number is used for other things.

Not ideal, I guess. But you have to hope package authors appropriately sub-typed the types they made.

1 Like

It turns out that SimpleTraits.jl can in fact solve this. See the reply to my issue:

1 Like