# Unexpected problem with previously working code - multiple dispatch seems to be failing

**URL:** https://discourse.julialang.org/t/unexpected-problem-with-previously-working-code-multiple-dispatch-seems-to-be-failing/118622
**Category:** New to Julia
**Created:** [August 26, 2024, 1:42pm UTC](https://discourse.julialang.org/t/unexpected-problem-with-previously-working-code-multiple-dispatch-seems-to-be-failing/118622 "2024-08-26T13:42:48Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![benoitseron](https://avatars.discourse-cdn.com/v4/letter/b/85f322/32.png) [@benoitseron](https://discourse.julialang.org/u/benoitseron)
#### Post date: [August 26, 2024, 1:42pm UTC](https://discourse.julialang.org/t/unexpected-problem-with-previously-working-code-multiple-dispatch-seems-to-be-failing/118622/1 "2024-08-26T13:42:48Z")

</div>

I came back from vacations and started to work on my code again. Some code that was working previously doesn’t seem to work anymore, while I don’t think I made any modifications to the code (updated my machine, but nothing major).

The issues goes along the lines of having a bit of code as:

```julia
foo(;a::Type1, b::Int, c:: ... ) = ...
foo(;a::Type2) = ...

```

When calling foo with a Type2, julia seems to want to use the first function, even though they are incompatible. Previously, this bit of code was working as intended. I am encountering this issue with multiple functions working with multiple dispatch.

A practical example in my code would be

```julia

function get_eigenvector_x_q_space(;x::Vector, q::Vector, eigenvectors, eigenstates_analytical_e, eigenstates_analytical_ph, eigenvector_index::Int, n_basis_states_e::Int, n_basis_states_ph::Int, atol = TOLERANCE_WAVE_FUNCTION_NORMALIZATION_2DOF) 

# some more code 

end

function get_eigenvector_x_q_space(;eigenvector_index::Int, k_y_index::Int, params::SimulationParameters, sim_results::SimulationResults2D, atol = TOLERANCE_WAVE_FUNCTION_NORMALIZATION_2DOF)

    # construction the wave function for the full state using the basis 

    @unpack n_basis_states_e, n_basis_states_ph = params

    x = sim_results.x_grid_array[1]
    q = sim_results.q_grid_array[1]
    eigenvectors = sim_results.eigenvectors_array[k_y_index]
    eigenstates_analytical_e = sim_results.eigenstates_analytical_e_array[k_y_index]
    eigenstates_analytical_ph = sim_results.eigenstates_analytical_ph_array[k_y_index]

    get_eigenvector_x_q_space(x = x, q = q, eigenvectors = eigenvectors, eigenstates_analytical_e = eigenstates_analytical_e, eigenstates_analytical_ph = eigenstates_analytical_ph, eigenvector_index = eigenvector_index, atol = atol, n_basis_states_e = n_basis_states_e, n_basis_states_ph = n_basis_states_ph)

end

```

Calling

```julia
get_eigenvector_x_q_space(eigenvector_index=1, k_y_index=1, params = params_int, sim_results = sim_results_int)

```

results in

```julia

ERROR: UndefKeywordError: keyword argument `k_y_index` not assigned
Stacktrace:
 [1] 
   @ Main ~/Documents/postdoc_freiburg/valery/quantum_hall_effect_cavity/julia/quantum_hall_with_cavity/2d_states_representation.jl:64
 [2] top-level scope
   @ ~/Documents/postdoc_freiburg/valery/quantum_hall_effect_cavity/julia/quantum_hall_with_cavity/main.jl:155
Some type information was truncated. Use `show(err)` to see complete types.

julia> show(err)
1-element ExceptionStack:
LoadError: UndefKeywordError: keyword argument `k_y_index` not assigned
Stacktrace:
  [1] get_eigenvector_x_q_space(; eigenvector_index::Int64, k_y_index::Int64, params::SimulationParameters, sim_results::SimulationResults2D, atol::Float64)
    @ Main ~/Documents/postdoc_freiburg/valery/quantum_hall_effect_cavity/julia/quantum_hall_with_cavity/2d_states_representation.jl:64
  [2] top-level scope
    @ ~/Documents/postdoc_freiburg/valery/quantum_hall_effect_cavity/julia/quantum_hall_with_cavity/main.jl:155
  [3] eval
    @ ./boot.jl:385 [inlined]
  [4] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
    @ Base ./loading.jl:2076
  [5] invokelatest(::Any, ::Any, ::Vararg{Any}; kwargs::@Kwargs{})
    @ Base ./essentials.jl:892
  [6] invokelatest(::Any, ::Any, ::Vararg{Any})
    @ Base ./essentials.jl:889
  [7] inlineeval(m::Module, code::String, code_line::Int64, code_column::Int64, file::String; softscope::Bool)
    @ VSCodeServer ~/.vscode/extensions/julialang.language-julia-1.120.2/scripts/packages/VSCodeServer/src/eval.jl:271
  [8] (::VSCodeServer.var"#69#74"{Bool, Bool, Bool, Module, String, Int64, Int64, String, VSCodeServer.ReplRunCodeRequestParams})()
    @ VSCodeServer ~/.vscode/extensions/julialang.language-julia-1.120.2/scripts/packages/VSCodeServer/src/eval.jl:181
  [9] withpath(f::VSCodeServer.var"#69#74"{Bool, Bool, Bool, Module, String, Int64, Int64, String, VSCodeServer.ReplRunCodeRequestParams}, path::String)
    @ VSCodeServer ~/.vscode/extensions/julialang.language-julia-1.120.2/scripts/packages/VSCodeServer/src/repl.jl:276
 [10] (::VSCodeServer.var"#68#73"{Bool, Bool, Bool, Module, String, Int64, Int64, String, VSCodeServer.ReplRunCodeRequestParams})()
    @ VSCodeServer ~/.vscode/extensions/julialang.language-julia-1.120.2/scripts/packages/VSCodeServer/src/eval.jl:179
 [11] hideprompt(f::VSCodeServer.var"#68#73"{Bool, Bool, Bool, Module, String, Int64, Int64, String, VSCodeServer.ReplRunCodeRequestParams})
    @ VSCodeServer ~/.vscode/extensions/julialang.language-julia-1.120.2/scripts/packages/VSCodeServer/src/repl.jl:38
 [12] (::VSCodeServer.var"#67#72"{Bool, Bool, Bool, Module, String, Int64, Int64, String, VSCodeServer.ReplRunCodeRequestParams})()
    @ VSCodeServer ~/.vscode/extensions/julialang.language-julia-1.120.2/scripts/packages/VSCodeServer/src/eval.jl:150
 [13] with_logstate(f::Function, logstate::Any)
    @ Base.CoreLogging ./logging.jl:515
 [14] with_logger
    @ ./logging.jl:627 [inlined]
 [15] (::VSCodeServer.var"#66#71"{VSCodeServer.ReplRunCodeRequestParams})()
    @ VSCodeServer ~/.vscode/extensions/julialang.language-julia-1.120.2/scripts/packages/VSCodeServer/src/eval.jl:263
 [16] #invokelatest#2
    @ ./essentials.jl:892 [inlined]
 [17] invokelatest(::Any)
    @ Base ./essentials.jl:889
 [18] (::VSCodeServer.var"#64#65")()
    @ VSCodeServer ~/.vscode/extensions/julialang.language-julia-1.120.2/scripts/packages/VSCodeServer/src/eval.jl:34
in expression starting at /home/benoitseron/Documents/postdoc_freiburg/valery/quantum_hall_effect_cavity/julia/quantum_hall_with_cavity/main.jl:155
julia> 

```

I am not sure how to attack this problem. It feels like I am missing something elementary, but I am quite confident that this code was working fine previously. Renaming the first function to some other name, to avoid the use of multiple dispatch, solves the issue, but is not a very elegant solution as this problem seems to be popping up everywhere in my code.

---

<div class="post-metadata">

### Author: ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)
#### Post date: [August 26, 2024, 1:47pm UTC](https://discourse.julialang.org/t/unexpected-problem-with-previously-working-code-multiple-dispatch-seems-to-be-failing/118622/2 "2024-08-26T13:47:42Z")

</div>

See the [documentation about methods](https://docs.julialang.org/en/v1/manual/methods/#Note-on-Optional-and-keyword-Arguments):

> Keyword arguments behave quite differently from ordinary positional arguments. In particular, they do not participate in method dispatch.

Since you are using the same name for the same signature (ignoring keyword arguments) you will overwrite some methods too. You can see this if you start julia with `--warn-overwrite=yes`:

```julia
julia> f(; x = 1) = x
f (generic function with 1 method)

julia> f(; y = 1) = y
WARNING: Method definition f() in module Main at REPL[1]:1 overwritten at REPL[2]:1.
WARNING: Method definition kwcall(NamedTuple{names, T} where T<:Tuple where names, typeof(Main.f)) in module Main at REPL[1]:1 overwritten at REPL[2]:1.
f (generic function with 1 method)

```

Note that there is still just one method, the one with `y` as keyword argument:

```julia
julia> f(x = 2)
ERROR: MethodError: no method matching f(; x::Int64)

Closest candidates are:
  f(; y) got unsupported keyword argument "x"
   @ Main REPL[2]:1

julia> f(y = 2)
2

```

---

<div class="post-metadata">

### Author: ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)
#### Post date: [August 26, 2024, 2:28pm UTC](https://discourse.julialang.org/t/unexpected-problem-with-previously-working-code-multiple-dispatch-seems-to-be-failing/118622/3 "2024-08-26T14:28:45Z")

</div>

> [@benoitseron](#):
>
> ```julia
> foo(;a::Type1, b::Int, c:: ... ) = ...
> foo(;a::Type2) = ...
> 
> ```

If you did want to use keyword arguments for everything, you could forward the arguments to another function.

```julia
julia> struct Type1 end

julia> struct Type2 end                                               

julia> foo(;a::Union{Type1, Type2}, kwargs...) = _foo(a; kwargs...)
foo (generic function with 1 method)

julia> _foo(a::Type1; b::Int) = @info "Type1 says hello" b                 
_foo (generic function with 1 method)

julia> _foo(a::Type2) = @info "Type2 dice hola"
_foo (generic function with 2 methods)

julia> foo(; a = Type1(), b=2)
┌ Info: Type1 says hello
└ b = 2

julia> foo(; a = Type2())
[ Info: Type2 dice hola

```

---

<div class="post-metadata">

### Author: ![benoitseron](https://avatars.discourse-cdn.com/v4/letter/b/85f322/32.png) [@benoitseron](https://discourse.julialang.org/u/benoitseron)
#### Post date: [August 27, 2024, 9:44am UTC](https://discourse.julialang.org/t/unexpected-problem-with-previously-working-code-multiple-dispatch-seems-to-be-failing/118622/4 "2024-08-27T09:44:42Z")

</div>

Thanks, this seems neat. I’ve never seen this “method” before, is it considered standard? Does it have a technical name?

---

<div class="post-metadata">

### Author: ![benoitseron](https://avatars.discourse-cdn.com/v4/letter/b/85f322/32.png) [@benoitseron](https://discourse.julialang.org/u/benoitseron)
#### Post date: [August 27, 2024, 9:45am UTC](https://discourse.julialang.org/t/unexpected-problem-with-previously-working-code-multiple-dispatch-seems-to-be-failing/118622/5 "2024-08-27T09:45:36Z")

</div>

> [@fredrikekre](#):
>
> Keyword arguments behave quite differently from ordinary positional arguments. In particular, they do not participate in method dispatch.

Thanks a lot, this solved the issue. I am wondering why keyword arguments would behave differently, however? What was the reason for this design choice? This seems quite counter-intuitive to me.

---

<div class="post-metadata">

### Author: ![Satvik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/satvik/32/20486_2.png) [@Satvik](https://discourse.julialang.org/u/Satvik)
#### Post date: [August 27, 2024, 5:43pm UTC](https://discourse.julialang.org/t/unexpected-problem-with-previously-working-code-multiple-dispatch-seems-to-be-failing/118622/6 "2024-08-27T17:43:48Z")

</div>

See this thread: [What is the motivation for Julia not dispatching on keyword arguments?](https://discourse.julialang.org/t/what-is-the-motivation-for-julia-not-dispatching-on-keyword-arguments/117447)

And the linked github issue: [keyword arguments · Issue #485 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/485)

The key issue seems to be that if you have n optional arguments, generating a method with and without each one would mean 2^n methods.
