Determine whether any one-argument method exists

question

#1

I would like to check whether a function f has any one-argument methods. Since Union{} <: [any type], I would argue that the following should work:

hasmethod(f, Tuple{Union{}})

It seems to only work if f has a one-argument method with abstract argument, however:

julia> hasmethod((::Integer)->nothing,Tuple{Union{}})
true

julia> hasmethod((::Int)->nothing,Tuple{Union{}})
false

This seems like a bug in the language (albeit arguable not the most severe one). Is there a workaround for this?


#2

It’s not a bug. hasmethod(f, Tuple{Union{}}) or hasmethod(f, Tuple{Any}) are asking whether f has a method whose argument type is Any or any supertype of Any, not any subtype which is what you are hoping for.

For example, hasmethod(f, Tuple{Real}) will succeed if there is an f(x::Real) method, but also if there is an f(x::Number) or f(x::Any) method. It won’t succeed if there is only an f(x::Int) method.

One thing you could do to check whether f has a single-argument method would be to check any(m -> m.nargs == 2, methods(f)), although this relies on the undocumented internal field nargs of the Method type. (m.nargs == 2 seems to be correct for to test for 1 argument, since the function itself is apparently counted as an “argument” here.)

Update: My bad, I was confusing Union{} with Any. As was pointed out below, Union{} is a supertype of every type, so it seems like it should work.


Mutable struct vs closure
#3

I’m not sure I understand. hasmethod(f,Tuple{T}) asks whether there is a method f(::U) such that T <: U, correct? And the documentation says

all types are supertypes of Union{}

So I don’t see why the way I use hasmethod should not be correct.


#4

Which is why I thought that the approach would work, since

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

julia> hasmethod(f, Tuple{Union{}})
false

julia> Union{} <: Int
true

ie Int is a supertype of Union{}, as all things are.


#5

Whoops, right, my bad; I got confused between Union{} (the bottom type) and Any (the top type).


#6

Frankly, I think this is a bug. If you open an issue, please link it here.


#7