# Use of methods()

**URL:** <https://discourse.julialang.org/t/use-of-methods/42478>\
**Category:** New to Julia\
**Created:** [July 3, 2020, 3:05pm UTC](https://discourse.julialang.org/t/use-of-methods/42478 "2020-07-03T15:05:20Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![erlebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/erlebach/32/12973_2.png) [@erlebach](https://discourse.julialang.org/u/erlebach)\
**Post date:** [July 3, 2020, 3:05pm UTC](https://discourse.julialang.org/t/use-of-methods/42478/1 "2020-07-03T15:05:20Z")

</div>

I would like to understand the use of `methods(function, types)`. Consider the following two invocations, whose results are not the same. This implies that the order in which the types are listed in the second argument impacts the return. Is this a bug or expected behavior? Thanks.

```julia
methods(+, [Int,Float])
methods(+, [Real, Int])

```

```julia
methods(+, [Real,Int])
# 6 methods for generic function "+":
[1] +(x::BigInt, c::Union{Int16, Int32, Int64, Int8}) in Base.GMP at gmp.jl:527
[2] +(x::BigFloat, c::Union{Int16, Int32, Int64, Int8}) in Base.MPFR at mpfr.jl:394
[3] +(x::T, y::T) where T<:Union{Int128, Int16, Int32, Int64, Int8, UInt128, UInt16, UInt32, UInt64, UInt8} in Base at int.jl:53
[4] +(a::Integer, b::Integer) in Base at int.jl:857
[5] +(x::T, y::T) where T<:Number in Base at promotion.jl:384
[6] +(x::Number, y::Number) in Base at promotion.jl:311

```

```julia
methods(+, [Int,Real])
# 7 methods for generic function "+":
[1] +(x::T, y::T) where T<:Union{Int128, Int16, Int32, Int64, Int8, UInt128, UInt16, UInt32, UInt64, UInt8} in Base at int.jl:53
[2] +(c::Union{Int16, Int32, Int64, Int8}, x::BigInt) in Base.GMP at gmp.jl:528
[3] +(a::Integer, b::Integer) in Base at int.jl:857
[4] +(c::Union{Int16, Int32, Int64, Int8}, x::BigFloat) in Base.MPFR at mpfr.jl:398
[5] +(x::Integer, y::Ratios.SimpleRatio) in Ratios at /Users/erlebach/.julia/packages/Ratios/uRs4y/src/Ratios.jl:29
[6] +(x::T, y::T) where T<:Number in Base at promotion.jl:384
[7] +(x::Number, y::Number) in Base at promotion.jl:311

```

Here are results when I invoke `methods` with a single type at a time:

```julia
methods(+,[Int])
# 1 method for generic function "+":
[1] +(x::Number) in Base at operators.jl:504

methods(+,[Real])
# 3 methods for generic function "+":
[1] +(x::Bool) in Base at bool.jl:93
[2] +(x::Rational) in Base at rational.jl:247
[3] +(x::Number) in Base at operators.jl:504

methods(+,[Int])
# 1 method for generic function "+":
[1] +(x::Number) in Base at operators.jl:504

```

Given these results, I would expect that using two types would generate 4 results, not 6 or 7. There is clearly something I do not understand in how `methods` is supposed to work.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [July 3, 2020, 3:12pm UTC](https://discourse.julialang.org/t/use-of-methods/42478/2 "2020-07-03T15:12:02Z")

</div>

> [@erlebach](#):
>
> results are not the same. This implies that the order in which the types are listed in the second argument impacts the return

Generally the order would of course matter — multiple dispatch does not care that `+` is commutative for certain domains, it may not be implemented in a way that reflects this.

---

<div class="post-metadata">

**Author:** ![erlebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/erlebach/32/12973_2.png) [@erlebach](https://discourse.julialang.org/u/erlebach)\
**Post date:** [July 3, 2020, 3:31pm UTC](https://discourse.julialang.org/t/use-of-methods/42478/3 "2020-07-03T15:31:15Z")

</div>

This dependence should be made clear in the documentation. It is hardly obvious. Lists of arguments are well defined, aren’t they? Could somebody please provide a MWE to demonstrate why it is obvious that order is important? The documentation implies that if I use `types=[Int,Real]`, the methods should return all functions that have an argument that is _either_ of type `Int` or of type `Real`.

I also do not understand why the total number of results with `types=[Int]` or `types=[Real]` adds up to less than the results using both types in a list. Perhaps this is expected behavior, but I do not understand it. There is no implication that the search only applies to the type of the first argument.

Here is a specific example. `methods(+,[Int,Real])` returns a list of 7 methods, including

```julia
[3] +(a::Integer, b::Integer) in Base at int.jl:857

```

My question is: why isn’t this method returned when invoking `methods(+,[Int])`?

I understand that this might be expected behavior, but I do not understand the behavior. Thanks.

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [July 3, 2020, 3:42pm UTC](https://discourse.julialang.org/t/use-of-methods/42478/4 "2020-07-03T15:42:39Z")

</div>

I think you may be misinterpreting what `methods` does.

`methods(+, [Integer, Real])` returns all methods whose first argument is an `Integer` and whose second argument is a `Real`.

Lets assume everyone implements methods symmetricly, which as Tamas noted is required because Julia doesn’t know that `+` is commutative.

Since there are more `Real` types than integer types, the number of returns is `num_integer_types * num_real_types`, which is not `N^2`.

There could also be weird performance reasons that something like `BigInt + Float64` is defined in a particular way but not `Float64 + BigInt`. I don’t know if that’s true but I could imagine that scenario.

Also note that

```julia
julia> +(4)
4

```

So someone has defined one-argument methods for `+` probably for some convenience reason.

---

<div class="post-metadata">

**Author:** ![erlebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/erlebach/32/12973_2.png) [@erlebach](https://discourse.julialang.org/u/erlebach)\
**Post date:** [July 3, 2020, 4:18pm UTC](https://discourse.julialang.org/t/use-of-methods/42478/5 "2020-07-03T16:18:40Z")

</div>

Thank you, that makes sense. Note that if you invoke help in REPL, one gets

```julia

methods(f, [types], [module])

Return the method table for f.

If types is specified, return an array of methods whose types match. If module is specified, return an array of methods defined in that module. A list of modules can also be specified as an array.

```

There is no implication that types refer to a list of arguments in the same order as in the method definitions. Perhaps the definition could be amended?

Here is a MWE to test out some assumptions:

```julia
function Gordon(a::Real)
println(a)
end

methods(Gordon)
methods(Gordon, types=[Real])

```

The two invocations of `methods` return:

```julia
methods(Gordon)

# 1 method for generic function "Gordon":
[1] Gordon(a::Real) in Main at /Users/erlebach/covid_modeling_julia/julia_code/sir-julia/SIRsims/gordon_julia_code/household_workplaces_leon/xxx.jl:395

```

as expected, and

```julia

methods(Gordon, types=[Real])
ERROR: MethodError: no method matching methods(::typeof(Gordon); types=DataType[Real])
Closest candidates are:
methods(::Any) at reflection.jl:905 got unsupported keyword argument "types"
methods(::Any, ::Union{Nothing, Module, AbstractArray{Module,N} where N}) at reflection.jl:905 got unsupported keyword argument "types"
methods(::Any, ::Any) at reflection.jl:879 got unsupported keyword argument "types"
...
Stacktrace:
[1] top-level scope at none:0

```

which is not expected. This is probably the simplest case I can think of. In this case, my function is in the Global space and not within a `Module`. Should that make a difference? Thank you.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [July 3, 2020, 5:02pm UTC](https://discourse.julialang.org/t/use-of-methods/42478/7 "2020-07-03T17:02:04Z")

</div>

```julia
julia> methods(Gordon, [Real])
# 1 method for generic function "Gordon":
[1] Gordon(a::Real) in Main at REPL[1]:1

To edit a specific method, type the corresponding number into the REPL and press Ctrl+Q

```

No where in the doc it mentions that `types` can be a keyword argument. This is not following the python convention.

You can see from the error that it is complaining about `methods` which has nothing to do with your function.

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [July 3, 2020, 6:29pm UTC](https://discourse.julialang.org/t/use-of-methods/42478/8 "2020-07-03T18:29:15Z")

</div>

I have to agree with @erlebach in one thing, the documentation below is incredibly vague and unhelpful. Someone can only guess what it means, and then check by experiment.

> [@erlebach](#):
>
> `If types is specified, return an array of methods whose types match.`

---

<div class="post-metadata">

**Author:** ![erlebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/erlebach/32/12973_2.png) [@erlebach](https://discourse.julialang.org/u/erlebach)\
**Post date:** [July 3, 2020, 5:28pm UTC](https://discourse.julialang.org/t/use-of-methods/42478/9 "2020-07-03T17:28:47Z")

</div>

Gordon Erlebacher  
Chair, Department of Scientific Computing

---

<div class="post-metadata">

**Author:** ![erlebach1](https://avatars.discourse-cdn.com/v4/letter/e/ed655f/32.png) [@erlebach1](https://discourse.julialang.org/u/erlebach1)\
**Post date:** [July 3, 2020, 7:28pm UTC](https://discourse.julialang.org/t/use-of-methods/42478/10 "2020-07-03T19:28:56Z")

</div>

Here is the source code for

> methods()

. There is definitely a type argument, notwithstanding the implications of the error message.

> “”" methods(f, [types], [module])  
> the method table for `f`.  
> If `types` is specified, return an array of methods whose types match.  
> If `module` is specified, return an array of methods defined in that module.  
> A list of modules can also be specified as an array.  
> !!! compat “Julia 1.4”  
> At least Julia 1.4 is required for specifying a module.  
> “”"  
> function methods(@nospecialize(f), @nospecialize(t),  
> @nospecialize(mod::Union{Module,AbstractArray{Module},Nothing}=nothing))  
> if mod isa Module  
> mod = (mod,)  
> end  
> if isa(f, Core.Builtin)  
> throw(ArgumentError(“argument is not a generic function”))  
> end  
> t = to\_tuple\_type(t)  
> world = typemax(UInt)  
> MethodList(Method[m[3] for m in \_methods(f, t, -1, world) if mod === nothing || m[3].module in mod],  
> typeof(f).name.mt)  
> end

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [July 3, 2020, 7:36pm UTC](https://discourse.julialang.org/t/use-of-methods/42478/11 "2020-07-03T19:36:06Z")

</div>

> [@erlebach1](#):
>
> . There is definitely a type argument, notwithstanding the implications of the error message.

This is not python, having an argument named `a` does not mean you can call the function with `a=...`. It’s also not named `types` FWIW…

---

<div class="post-metadata">

**Author:** ![erlebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/erlebach/32/12973_2.png) [@erlebach](https://discourse.julialang.org/u/erlebach)\
**Post date:** [July 3, 2020, 8:10pm UTC](https://discourse.julialang.org/t/use-of-methods/42478/12 "2020-07-03T20:10:05Z")

</div>

I appreciate all the replies. The command

```julia
methods(Gordon, [Real])

```

works perfectly well. I must have had a typo, and no doubt, I used `types=` in a past thread, which was most assuredly, incorrect. Thank you for your patience with me.
