# Method overloading doesn't work inside a function

**URL:** <https://discourse.julialang.org/t/method-overloading-doesnt-work-inside-a-function/88339>\
**Category:** General Usage\
**Tags:** scope, functions\
**Created:** [October 6, 2022, 11:04am UTC](https://discourse.julialang.org/t/method-overloading-doesnt-work-inside-a-function/88339 "2022-10-06T11:04:20Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![wsshin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wsshin/32/360_2.png) [@wsshin](https://discourse.julialang.org/u/wsshin)\
**Post date:** [October 6, 2022, 11:04am UTC](https://discourse.julialang.org/t/method-overloading-doesnt-work-inside-a-function/88339/1 "2022-10-06T11:04:20Z")

</div>

The following method overloading works:

```julia-repl
julia> VERSION
v"1.8.0"

julia> myfun1(x, y) = x+y # method to overload
myfun1 (generic function with 1 method)

julia> myfun1(x) = myfun1(x, 1) # overloading
myfun1 (generic function with 2 methods)

julia> myfun1(3) # no error
4

```

However, inside another function, if I try to overload a method defined outside the function, it fails:

```julia-repl
julia> myfun2(x, y) = x+y # method to overload
myfun2 (generic function with 1 method)

julia> function wrapper(x)
           myfun2(x) = myfun2(x, 1) # overloading
           val = myfun2(x)
           return val
       end
wrapper (generic function with 1 method)

julia> wrapper(3) # error
ERROR: MethodError: no method matching (::var"#myfun2#3")(::Int64, ::Int64)
Closest candidates are:
  (::var"#myfun2#3")(::Any) at REPL[8]:2
Stacktrace:
 [1] (::var"#myfun2#3")(x::Int64)
   @ Main ./REPL[8]:2
 [2] wrapper(x::Int64)
   @ Main ./REPL[8]:4
 [3] top-level scope
   @ REPL[9]:1

```

Why does this not work? Is there a way to make this work?

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [October 6, 2022, 11:30am UTC](https://discourse.julialang.org/t/method-overloading-doesnt-work-inside-a-function/88339/2 "2022-10-06T11:30:18Z")

</div>

> [@wsshin](#):
>
> ```julia
> function wrapper(x)
> myfun2(x) = myfun2(x, 1) # overloading
> 
> ```

This is not overloading — you’re declaring a _new_ local function `myfun2` that happens to have the same name ([shadows](https://en.wikipedia.org/wiki/Variable_shadowing)) the global function `myfunc2`, in the same way that typing `x = 1` in a function does not overwrite a global variable named `x` unless you use `global`.

The only way to do this in a function is to use `eval`, e.g.:

```julia
function wrapper(x)
    @eval myfun2(x) = myfun2(x, 1) # overloading
    return Base.invokelatest(myfun2, x)
end

```

However, it’s pretty rare that you should actually need to do this. What are you trying to accomplish?

---

<div class="post-metadata">

**Author:** ![wsshin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wsshin/32/360_2.png) [@wsshin](https://discourse.julialang.org/u/wsshin)\
**Post date:** [October 6, 2022, 2:21pm UTC](https://discourse.julialang.org/t/method-overloading-doesnt-work-inside-a-function/88339/3 "2022-10-06T14:21:56Z")

</div>

Thanks for the explanation! I was not trying to accomplish anything exotic; I just wanted to define an inner function `myfun2(x)` that would play a nearly identical role as the outer function `myfun2(x, y)` except for a fixed parameter `y = 1`. I didn’t want to give a new name to the inner function because its role would be similar to the outer function’s, but I was surprised that it didn’t work.

But I still don’t quite understand why Julia is designed to generate an error in my attempted use case. Even though the inner function name shadows the outer function name, its signature is different with a different number of arguments, so isn’t there enough information to discriminate the inner function call from the outer function call? The dispatch system will get confused if I additionally define `myfun2(x)` outside `wrapper()` later. Maybe the design decision was made to avoid such confusion?

---

<div class="post-metadata">

**Author:** ![Jeff\_Emanuel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff_emanuel/32/15440_2.png) [@Jeff\_Emanuel](https://discourse.julialang.org/u/Jeff_Emanuel)\
**Post date:** [October 6, 2022, 2:37pm UTC](https://discourse.julialang.org/t/method-overloading-doesnt-work-inside-a-function/88339/4 "2022-10-06T14:37:39Z")

</div>

I think the design choice here is that scoping rules for function names is no different than for other variables. Your call to `myfun2(x, 1)` resolves to the `myfun2` defined within `wrapper` as stevengj pointed out. There is no special case that would say, "if the local scope function found does not have the same signature as the call, then look in an outer scope`. Consistency makes scoping reasoning easier for both the user and the compiler.

---

<div class="post-metadata">

**Author:** ![palday](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palday/32/12640_2.png) [@palday](https://discourse.julialang.org/u/palday)\
**Post date:** [October 6, 2022, 2:41pm UTC](https://discourse.julialang.org/t/method-overloading-doesnt-work-inside-a-function/88339/5 "2022-10-06T14:41:13Z")

</div>

Have you seen [`Base.Fix1`](https://docs.julialang.org/en/v1/base/base/#Base.Fix1) and `Base.Fix2`?

---

<div class="post-metadata">

**Author:** ![mikmoore](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikmoore/32/31109_2.png) [@mikmoore](https://discourse.julialang.org/u/mikmoore)\
**Post date:** [October 6, 2022, 2:54pm UTC](https://discourse.julialang.org/t/method-overloading-doesnt-work-inside-a-function/88339/6 "2022-10-06T14:54:41Z")

</div>

To elaborate a little on what others have said: the `myfun2` inside your function is not the same function as the `myfun2` outside of it. They live in different scopes. What you’re trying fails for the same reason that you can write

```julia
function f(x)
  sum = zero(eltype(x))
  for xx in x
    sum += xx
  end
  return sum
end

```

without obliterating the `sum` function everywhere.

I think the `Base.Fix2` suggestion is a good solution for this example. Otherwise, name your inner function something else to avoid this shadowing. Alternatively, move your inner function definition to the outer scope (although perhaps you didn’t want that default value to apply in general, hence your inner definition attempt).

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [October 6, 2022, 3:04pm UTC](https://discourse.julialang.org/t/method-overloading-doesnt-work-inside-a-function/88339/7 "2022-10-06T15:04:58Z")

</div>

> [@wsshin](#):
>
> define an inner function `myfun2(x)` that would play a nearly identical role as the outer function `myfun2(x, y)` except for a fixed parameter `y = 1`.

You could always use `x -> myfun2(x, 1)`, or define `myfun2_1(x) = myfun2(x, 1)`. (I hope someday we can [get the syntax `myfun2(_, 1)`](https://github.com/JuliaLang/julia/pull/24990), but I’m not holding my breath.)

The basic issue is that if you were to add methods to the global function `myfun2` itself, it would affect _everything_ using `myfun2`. That’s why it can only be done using `eval`, and probably isn’t a good idea.
