Skip to content

Improving MethodError message for anonymous functions #56325

Open
@fonsp

Description

@fonsp

Context: improving error experience for beginner Julia programmers.

In this example, you get a MethodError for your anonymous method (::var"#3#4"):

julia> vals = [5,6,10,20];

julia> accumulate(vals; init=0) do (old, new)
           old + new
       end
ERROR: MethodError: no method matching (::var"#3#4")(::Int64, ::Int64)
The function `#3` exists, but no method is defined for this combination of argument types.

Closest candidates are:
  (::var"#3#4")(::Any)
   @ Main REPL[2]:2

Stacktrace:
 [1] _accumulate!(op::var"#3#4", B::Vector{Union{}}, A::Vector{Int64}, dims::Nothing, init::Some{Int64})
   @ Base ./accumulate.jl:368
 [2] accumulate!(op::Function, B::Vector{Union{}}, A::Vector{Int64}; dims::Nothing, kw::@Kwargs{init::Int64})
   @ Base ./accumulate.jl:350
 [3] accumulate(op::Function, A::Vector{Int64}; dims::Nothing, kw::@Kwargs{init::Int64})
   @ Base ./accumulate.jl:291
 [4] top-level scope
   @ REPL[2]:1

The problem is that my do syntax used (old, new) (a single tuple argument) instead of old, new (two integer arguments):

julia> accumulate(vals; init=0) do old, new
           old + new
       end
4-element Vector{Int64}:
  5
 11
 21
 41

But the error is difficult to understand!

Ideas

I have seen this pattern more often (MethodError on an anonymous function that I defined), and I think we could make meaningful improvements to this error message! Ideas:

  1. Say "anonymous function": We can communicate better that it's about an "anonymous function". The name var"#3#4" is not so useful for beginners. (In the case of a do-block, it might even be non-obvious that you wrote a function.)
  2. Simplify "Closest candidates": Anonymous functions can only have one method (right?). So instead of showing "Closest candidates", the error can be stated in a simpler way:
The anonymous function has signature:
   (::Any)
but it was called with types:
   (::Int64, ::Int64)
  1. Number of arguments: the function was called with 2 arguments, but no method accepts that. When dispatch fails because of the number of arguments, I think this is the most helpful bit of debugging info available (like a sanity check), and we could say this explicitly in the error.
    It could be phrased as advice (when the situation is simple enough):
Tip: The function was called with 2 arguments, but it only accepts 1 argument.

Metadata

Metadata

Assignees

No one assigned

    Labels

    error messagesBetter, more actionable error messagesgood first issueIndicates a good issue for first-time contributors to Julia

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions