# Multiple dispatch based on argument given?

**URL:** <https://discourse.julialang.org/t/multiple-dispatch-based-on-argument-given/58243>\
**Category:** New to Julia\
**Tags:** question, dispatch\
**Created:** [March 30, 2021, 3:34pm UTC](https://discourse.julialang.org/t/multiple-dispatch-based-on-argument-given/58243 "2021-03-30T15:34:59Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![RobertGregg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/robertgregg/32/22105_2.png) [@RobertGregg](https://discourse.julialang.org/u/RobertGregg)\
**Post date:** [March 30, 2021, 3:35pm UTC](https://discourse.julialang.org/t/multiple-dispatch-based-on-argument-given/58243/1 "2021-03-30T15:35:00Z")

</div>

I have a seemingly simple question. I’m creating a struct with multiple inner constructors and I want to dispatch different methods based on the arguments given. A simple example would be:

```julia
struct OrderedPair
    x::Real
    y::Real
    OrderedPair(x::Float64,y::Float64) = new(x,y)
    OrderedPair(x::Int64,y::Int64) = new(x+1,y-1)
    OrderedPair(;x) = new(x,x+1)
    OrderedPair(;y) = new(y,y+2)
end

```

However, when I check the methods created their are only three:

```julia
methods(OrderedPair)
# 3 methods for type constructor:
[1] OrderedPair(; y) in Main at REPL[1]:7
[2] OrderedPair(x::Float64, y::Float64) in Main at REPL[1]:4
[3] OrderedPair(x::Int64, y::Int64) in Main at REPL[1]:5

```

How do I ensure the third method isn’t overwritten?

---

<div class="post-metadata">

**Author:** ![mike](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mike/32/39_2.png) [@mike](https://discourse.julialang.org/u/mike)\
**Post date:** [March 30, 2021, 3:41pm UTC](https://discourse.julialang.org/t/multiple-dispatch-based-on-argument-given/58243/2 "2021-03-30T15:41:41Z")

</div>

Only positional arguments, not keywords, take part in dispatch the way you’d like. You can write a “multi-level” dispatch to make it work, kind of like below:

```julia
julia> fn(; x = nothing, y = nothing) = fn(x, y)
fn (generic function with 1 method)

julia> fn(x::Float64, ::Nothing) = (x, x + 1)
fn (generic function with 2 methods)

julia> fn(::Nothing, y::Float64) = (y, y + 2)
fn (generic function with 3 methods)

julia> fn(x = 1.0)
(1.0, 2.0)

julia> fn(y = 1.0)
(1.0, 3.0)

```

---

<div class="post-metadata">

**Author:** ![RobertGregg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/robertgregg/32/22105_2.png) [@RobertGregg](https://discourse.julialang.org/u/RobertGregg)\
**Post date:** [March 30, 2021, 4:00pm UTC](https://discourse.julialang.org/t/multiple-dispatch-based-on-argument-given/58243/3 "2021-03-30T16:00:44Z")

</div>

Fantastic! This works perfectly. Putting everything together it would look something like this then:

```julia
struct OrderedPair
    x::Real
    y::Real
    
    OrderedPair(x::Float64,y::Float64) = new(x,y)
    OrderedPair(x::Int64,y::Int64) = new(x+1,y-1)

    OrderedPair(;x=nothing,y=nothing) = OrderedPair(x,y)
    OrderedPair(x::Float64, ::Nothing) = new(x,x+1)
    OrderedPair(::Nothing, y::Float64) = new(y,y+2)
end

```

Which gives the desired result:

```julia
julia> OrderedPair(1.0,1.0)
OrderedPair(1.0, 1.0)

julia> OrderedPair(1,1)
OrderedPair(2, 0)

julia> OrderedPair(x=1.0)
OrderedPair(1.0, 2.0)

julia> OrderedPair(y=1.0)
OrderedPair(1.0, 3.0)

```
