# Struct with Multiple Dispatch

**URL:** https://discourse.julialang.org/t/struct-with-multiple-dispatch/53118
**Category:** General Usage
**Created:** [January 10, 2021, 3:22pm UTC](https://discourse.julialang.org/t/struct-with-multiple-dispatch/53118 "2021-01-10T15:22:04Z")
**Posts on this page:** 12
**Page:** 1

<div class="post-metadata">

### Author: ![TI36XPro](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ti36xpro/32/33658_2.png) [@TI36XPro](https://discourse.julialang.org/u/TI36XPro)
#### Post date: [January 10, 2021, 3:22pm UTC](https://discourse.julialang.org/t/struct-with-multiple-dispatch/53118/1 "2021-01-10T15:22:05Z")

</div>

Hello,

I’m new to Julia and am watching the Juliacon 2020 video series. I have a question about the use of a mutable struct in this video [here](https://www.youtube.com/watch?v=Gi4ZZVS2GLA&t=821s).

From what I am seeing, I think he defines a mutable struct with some fields, then defines two methods for that struct. So If I wanted to do something similar I could do

```julia
a = 3
b = 5

```

```julia
# Example of multiple dispatch with a mutable struct
begin
	mutable struct MyStruc
		C::Float64
		a::Int64
	end
	# Multiple dispatch of struct
	MyStruc(C::Float64; aValue=a) = MyStruc(C,aValue)
	MyStruc(C::Int64; bValue=b) = MyStruc(C,bValue)
end

```

That seems to work. But the syntax is strange to me, doing `MyStruc = MyStruc`. Am I correct there are two methods for this struct? I’m using Pluto and I don’t see “MyStruct with two methods” above the cell with the struct defined (unlike when I define a function with multiple methods and it does say the number of corresponding methods above the cell).

I also tried the following

```julia
# Example of multiple dispatch with a mutable struct
begin
	mutable struct MyStruc
		C::Float64
		a::Int64
	end
	# Multiple dispatch of struct
	MyStruc(C::Float64; aValue=a) = MyStruc(C,aValue)
	MyStruc(C::Int64, a::Float64) = MyStruc(C,a)
end

```

But when I try to use the second method like this

```julia
TestStruct = MyStruc(3, 101.1)

```

I get a StackOverflowError. Not sure why though - would appreciate any comments and insight on this.

---

<div class="post-metadata">

### Author: ![pbayer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pbayer/32/11675_2.png) [@pbayer](https://discourse.julialang.org/u/pbayer)
#### Post date: [January 10, 2021, 3:52pm UTC](https://discourse.julialang.org/t/struct-with-multiple-dispatch/53118/2 "2021-01-10T15:52:09Z")

</div>

```julia
mutable struct MyStruc
      C::Float64
      a::Int64
end

```

is enough.

```julia
julia> TestStruct = MyStruc(3.1, 101)
MyStruc(3.1, 101)

julia> TestStruct = MyStruc(3, 101)
MyStruc(3.0, 101)

```

but:

```julia
julia> TestStruct = MyStruc(3, 101.1)
ERROR: InexactError: Int64(101.1)
Stacktrace: ...

```

to avoid this you could define a method (multiple dispatch):

`MyStruc(C::Int64, a::Float64) = MyStruc(C, Int(round(a)))`

then you get:

```julia
julia> TestStruct = MyStruc(3, 101.1)
MyStruc(3.0, 101)

```

---

<div class="post-metadata">

### Author: ![sostock](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sostock/32/5546_2.png) [@sostock](https://discourse.julialang.org/u/sostock)
#### Post date: [January 10, 2021, 3:53pm UTC](https://discourse.julialang.org/t/struct-with-multiple-dispatch/53118/3 "2021-01-10T15:53:29Z")

</div>

[quote=“TI36XPro, post:1, topic:53118”]  
Am I correct there are two methods for this struct?

No, there are four. You can check with the `methods` function:

```julia
julia> methods(MyStruc)
# 4 methods for type constructor:
[1] MyStruc(C::Float64; aValue) in Main at REPL[2]:2
[2] MyStruc(C::Float64, a::Int64) in Main at REPL[1]:2
[3] MyStruc(C::Int64; bValue) in Main at REPL[3]:1
[4] MyStruc(C, a) in Main at REPL[1]:2

```

[1] and [3] are the methods you defined, and [2] and [4] are the default methods that are always defined when you create a new struct (unless you define inner constructors).

---

<div class="post-metadata">

### Author: ![TI36XPro](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ti36xpro/32/33658_2.png) [@TI36XPro](https://discourse.julialang.org/u/TI36XPro)
#### Post date: [January 10, 2021, 3:59pm UTC](https://discourse.julialang.org/t/struct-with-multiple-dispatch/53118/4 "2021-01-10T15:59:48Z")

</div>

Thank you for the reply. Why can’t I do

```julia
MyStruc(C::Int64, a::Float64) = MyStruc(C, a)
MyStruc(-3, 5.4)

```

I’m confused because in my original declaration I have `C::Float64` and it didn’t seem to mind defining a new method with that as an `Int64`. But if I try it the other way around, with `a` where it is initially an `Int64` in my original declaration and then later on I try to define a new method with it as a `Float64`, it gives me a stackoverflow error and I have to use round as you show, to work correctly.

Because of what it means to go from `Int` to `Float` and vice versa?

---

<div class="post-metadata">

### Author: ![sostock](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sostock/32/5546_2.png) [@sostock](https://discourse.julialang.org/u/sostock)
#### Post date: [January 10, 2021, 4:05pm UTC](https://discourse.julialang.org/t/struct-with-multiple-dispatch/53118/5 "2021-01-10T16:05:55Z")

</div>

It doesn’t have anything to do with the order of the definition. The problem is that in your second example, you define the method `MyStruc(C::Int64, a::Float64)` that always calls itself. Thus, you get a stack overflow (basically, the method ends up calling itself over and over again, so it can never return). In your first example, your methods have keyword arguments and call methods without keyword arguments, so none of the methods call themselves.

---

<div class="post-metadata">

### Author: ![pbayer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pbayer/32/11675_2.png) [@pbayer](https://discourse.julialang.org/u/pbayer)
#### Post date: [January 10, 2021, 4:08pm UTC](https://discourse.julialang.org/t/struct-with-multiple-dispatch/53118/6 "2021-01-10T16:08:32Z")

</div>

> [@TI36XPro](#):
>
> ```julia
> MyStruc(C::Int64, a::Float64) = MyStruc(C, a)
> MyStruc(-3, 5.4)
> 
> ```

This does **call only itself** since `5.4 isa Float64` and it matches only your method definition above but not your `struct`, which has an `Int64` as 2nd element. Therefore the stack overflow. It says you actually, which method it calls:

```julia
julia> TestStruct = MyStruc(3, 5.4)
ERROR: StackOverflowError:
Stacktrace:
 [1] MyStruc(::Int64, ::Float64) at ./REPL[64]:1 (repeats 79984 times)

```

you see it does not call your struct definition.

---

<div class="post-metadata">

### Author: ![TI36XPro](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ti36xpro/32/33658_2.png) [@TI36XPro](https://discourse.julialang.org/u/TI36XPro)
#### Post date: [January 10, 2021, 4:15pm UTC](https://discourse.julialang.org/t/struct-with-multiple-dispatch/53118/7 "2021-01-10T16:15:24Z")

</div>

Thank you both - I think that makes a little more sense now.

---

<div class="post-metadata">

### Author: ![TI36XPro](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ti36xpro/32/33658_2.png) [@TI36XPro](https://discourse.julialang.org/u/TI36XPro)
#### Post date: [January 10, 2021, 4:28pm UTC](https://discourse.julialang.org/t/struct-with-multiple-dispatch/53118/8 "2021-01-10T16:28:15Z")

</div>

One last question - you both said I was creating a method that called itself. Isn’t that what is happening here too? No keyword arguments are used to distinguish the method from itself like before. Yet, this does work. Because the presence of the `Int` function?

```julia
MyStruc(C::Float64, a::Float64) = MyStruc(C, Int(round(a)))

```

---

<div class="post-metadata">

### Author: ![pbayer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pbayer/32/11675_2.png) [@pbayer](https://discourse.julialang.org/u/pbayer)
#### Post date: [January 10, 2021, 4:33pm UTC](https://discourse.julialang.org/t/struct-with-multiple-dispatch/53118/9 "2021-01-10T16:33:35Z")

</div>

yes, that then matches your `struct` definition better with an `Int64` at the second place. So that gets dispatched as you probably want.

```julia
julia> MyStruc(C::Float64, a::Float64) = MyStruc(C, Int(round(a)))
MyStruc

julia> TestStruct = MyStruc(3, 101.1)
MyStruc(3.0, 101)

```

---

<div class="post-metadata">

### Author: ![FPGro](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fpgro/32/20822_2.png) [@FPGro](https://discourse.julialang.org/u/FPGro)
#### Post date: [January 10, 2021, 4:49pm UTC](https://discourse.julialang.org/t/struct-with-multiple-dispatch/53118/10 "2021-01-10T16:49:36Z")

</div>

> [@TI36XPro](#):
>
> `MyStruc(C::Float64, a::Float64) = MyStruc(C, Int(round(a)))`

This does not call itself because it has the signature `MyStruc(::Float64, ::Float64)` and converts the second float to Int, so it calls `MyStruc(::Float64, ::Int)` then. This is a different method of the same function. See:

> [@sostock](#):
>
> No, there are four. You can check with the `methods` function:
> 
> ```julia
> julia> methods(MyStruc)
> # 4 methods for type constructor:
> [1] MyStruc(C::Float64; aValue) in Main at REPL[2]:2
> [2] MyStruc(C::Float64, a::Int64) in Main at REPL[1]:2
> [3] MyStruc(C::Int64; bValue) in Main at REPL[3]:1
> [4] MyStruc(C, a) in Main at REPL[1]:2
> 
> ```

---

<div class="post-metadata">

### Author: ![TI36XPro](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ti36xpro/32/33658_2.png) [@TI36XPro](https://discourse.julialang.org/u/TI36XPro)
#### Post date: [January 10, 2021, 7:53pm UTC](https://discourse.julialang.org/t/struct-with-multiple-dispatch/53118/11 "2021-01-10T19:53:39Z")

</div>

Thank you all for explaining this to me and answering my questions.

One last thing. Am I technically creating multiple dispatches of a function called `MyStruc` by doing `MyStruc(C::Float64; aValue=a) = MyStruc(C,aValue)` and it just so happens I’ve also already defined a new type called `MyStruc`? I could just as easily have done the following?

```julia
begin
	mutable struct MyStruc
		C::Float64
		a::Int64
	end
	# Multiple dispatch of struct
	MyFunction(C::Float64; aValue=a) = MyStruc(C,aValue)
	MyFunction(C::Int64; bValue=b) = MyStruc(C,bValue)
end

```

If that’s the case - I’m not really creating multiple dispatches of a struct here am I? Sorry if I am overthinking things here.

---

<div class="post-metadata">

### Author: ![pbayer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pbayer/32/11675_2.png) [@pbayer](https://discourse.julialang.org/u/pbayer)
#### Post date: [January 10, 2021, 9:19pm UTC](https://discourse.julialang.org/t/struct-with-multiple-dispatch/53118/12 "2021-01-10T21:19:57Z")

</div>

I think it a bit misleading if you speak of “Multiple dispatch of struct”. There is multiple **function** dispatch. I’m starting with a fresh REPL here. I you define your `struct MyStruc`, you implicitly define a `function MyStruc` with two methods:

```julia
julia> mutable struct MyStruc
           C::Float64
           a::Int64
       end

julia> methods(MyStruc)
# 2 methods for type constructor:
[1] MyStruc(C::Float64, a::Int64) in Main at REPL[1]:2
[2] MyStruc(C, a) in Main at REPL[1]:2

```

but it does not do what you want, since

```julia
julia> MyStruc(123, 4.56)
ERROR: InexactError: Int64(4.56)
Stacktrace: ...

```

Therefore you define another method like

```julia
julia> MyStruc(C::Int64, a::Float64) = MyStruc(C, Int(round(a)))
MyStruc

julia> methods(MyStruc)
# 3 methods for type constructor:
[1] MyStruc(C::Float64, a::Int64) in Main at REPL[1]:2
[2] MyStruc(C::Int64, a::Float64) in Main at REPL[3]:1
[3] MyStruc(C, a) in Main at REPL[1]:2

julia> MyStruc(123, 4.56)
MyStruc(123.0, 5)

```

In your case then you create a 2nd function, `MyFunction` with two methods, dispatching on `Float64` and `Int64`:

```julia
julia> MyFunction(C::Float64; aValue) = MyStruc(C,aValue)
MyFunction (generic function with 2 methods)

julia> MyFunction(C::Int64; bValue) = MyStruc(C,bValue)
MyFunction (generic function with 2 methods)

julia> methods(MyFunction)
# 2 methods for generic function "MyFunction":
[1] MyFunction(C::Int64; bValue) in Main at REPL[7]:1
[2] MyFunction(C::Float64; aValue) in Main at REPL[6]:1

```

The problem with the 2nd parameter is not resolved by that since without the 3rd method for `MyStruc` above you get the same `InexactError` if you do `MyFunction(123, bValue=4.56)`. Therefore `MyFunction` does not help.

BTW: `MyFunction(C::Float64; aValue=a)` assumes `a` being a global variable or a constant present in the current scope.
