julia icon indicating copy to clipboard operation
julia copied to clipboard

Wrong number of methods after redefinition of function

Open giordano opened this issue 1 year ago • 6 comments

On latest master (52fc79696e0b08fe1793a001daaefd1d91d59f0c) the number of methods for a function for which we redefine the same method multiple times increases steadily:

julia> f() = nothing
f (generic function with 1 method)

julia> f() = nothing
f (generic function with 2 methods)

julia> f() = nothing
f (generic function with 3 methods)

julia> methods(f)
# 3 methods for generic function "f" from Main:
 [1] f()
     @ REPL[1]:1
 [2] f()
     @ REPL[1]:1
 [3] f()
     @ REPL[1]:1

julia> length(methods(f)) == 1
false

length(methods(f)) would be a good test for the resolution of this bug, or for a bisection script (can't run it myself now). This doesn't happen in v1.10 nor v1.11, so it should be somewhat recent.

giordano avatar Mar 22 '24 01:03 giordano

IIRC @vtjnash said this was intentional, but there was much complaining from pretty much anyone, so I think we need to think about this again, possibly by tweaking the display code to only display methods that are reachable in the current world.

Keno avatar Mar 22 '24 01:03 Keno

Bisected to https://github.com/JuliaLang/julia/pull/53415

christiangnrd avatar Mar 22 '24 17:03 christiangnrd

How about the following: We change the display code to only count methods which are reachable in the current world for some signature. Now, I don't believe we have that exact query in the type system, but I think something along the lines of typesubtract(m.sig, mapreduce(m2->m2.sig, Union, filter(!=(m), methods(m.sig)) !== Union{} would be pretty close. It's a little expensive to compute, but probably doesn't matter for interactive showing.

Keno avatar Apr 01 '24 20:04 Keno

I don't believe we have that exact query in the type system

It is exactly the query you get if specifying lim != -1, though it indeed is expensive. Of note though that this can be approximated quite well with a O(1) pair-wise check (and which is an exact if there is no ambiguities), as two type-egal methods must be adjacent in the output list, per the definition of morespecific, after filtering ambiguities.

vtjnash avatar Apr 01 '24 21:04 vtjnash

This also seems unexpected:

f() = 1
f() = 2

julia> methods(f, Tuple{})
# 1 method for generic function "f" from Main:
 [1] f()
     @ REPL[15]:1

julia> methods(f, Tuple{Vararg{Any}})
# 2 methods for generic function "f" from Main:
 [1] f()
     @ REPL[15]:1
 [2] f()
     @ REPL[14]:1

JeffBezanson avatar May 09 '24 19:05 JeffBezanson

The behavior of lim==-1 has always been that way for whether it chooses to filter out supertypes. I suppose because it happens to be O(n) whereas the filter for the general case is O(n^3), where n is the number of methods that matched

vtjnash avatar May 09 '24 20:05 vtjnash