# Do type annotations help Julia determine which method to call?

**URL:** https://discourse.julialang.org/t/do-type-annotations-help-julia-determine-which-method-to-call/60476
**Category:** General Usage
**Created:** [May 3, 2021, 5:26pm UTC](https://discourse.julialang.org/t/do-type-annotations-help-julia-determine-which-method-to-call/60476 "2021-05-03T17:26:09Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![anon60034542](https://avatars.discourse-cdn.com/v4/letter/a/90ced4/32.png) [@anon60034542](https://discourse.julialang.org/u/anon60034542)
#### Post date: [May 3, 2021, 5:26pm UTC](https://discourse.julialang.org/t/do-type-annotations-help-julia-determine-which-method-to-call/60476/1 "2021-05-03T17:26:09Z")

</div>

Consider the following methods:

```julia
function do_work(first::Number, second::Number)
    println("Calling function where the parameters are numbers.")
end

function do_work(first::Number,second::AbstractFloat)
    println("Calling method where the first parameter is a number, 
             and the second is an AbstractFloat")
end

```

In the documentation, we can see the hierarchy for `Int32` and `Float32`:

```julia
Number > Real > Integer > Signed > Int32
Number > Real > AbstractFloat > Float32

```

1. Do type annotations help Julia to determine which method to call?

```julia
number_one :: Int32 = 21
number_two :: Int32 = 47
number_float :: Float32 = 1.15

do_work(number_one,number_two)
do_work(number_two,number_float)

```

1. In what order does Julia check the arguments being passed, top to bottom, `Number > Real...` or bottom to top, `Int32 > Signed...` to determine which method to call?

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [May 3, 2021, 5:41pm UTC](https://discourse.julialang.org/t/do-type-annotations-help-julia-determine-which-method-to-call/60476/2 "2021-05-03T17:41:09Z")

</div>

> [@anon60034542](#):
>
> Do type annotations help Julia to determine which method to call?

No

> [@anon60034542](#):
>
> n what order does Julia check the arguments being passed, top to bottom, `Number > Real...` or bottom to top, `Int32 > Signed...` to determine which method to call?

I am not sure if the right question is being posed here. The most specific method will be called. Thus, if the second parameter `isa AbstractFloat`, the second method will be called.

---

<div class="post-metadata">

### Author: ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)
#### Post date: [May 3, 2021, 5:47pm UTC](https://discourse.julialang.org/t/do-type-annotations-help-julia-determine-which-method-to-call/60476/3 "2021-05-03T17:47:11Z")

</div>

> [@anon60034542](#):
>
> Do type annotations help Julia to determine which method to call?

Not, I suspect, in the way you’re thinking. Values in Julia have types, variables are just labels attached to those values.

With that said, type declarations do have an effect in that they implicitly try to `convert` the right-hand side to the specified type:

```julia
julia> function f()
         x::Float64 = 1
         @show typeof(x)
       end
f (generic function with 1 method)

julia> f()
typeof(x) = Float64

```

What happened here is that the `::Float64` declaration caused Julia to insert a call to `convert(Float64,...)` which does actually produce a _value_ of type `Float64`. You can see this in the `@code_lowered` output:

```julia
julia> @code_lowered f()
CodeInfo(
1 ─ %1 = Base.convert(Main.Float64, 1)
│ x = Core.typeassert(%1, Main.Float64)

```

So the `::Float64` turned into a call to `convert` and a call to `typeassert`. That means that you’ll get the same result here by doing:

```julia
julia> function g()
         x = convert(Float64, 1)
         @show typeof(x)
       end
g (generic function with 1 method)

julia> g()
typeof(x) = Float64

```

or more simply by doing `Float64(1)` or just `1.0`.

So the annotation that you added to a variable here had an effect, but only because the `convert` call that it inserted actually did change the type of the value being assigned to that variable.

This comes back to the same point here: [How does a dictionary store structs? - #2 by rdeits](https://discourse.julialang.org/t/how-does-a-dictionary-store-structs/57866/2) – there is no distinction between “compile-time” and “run-time” types in Julia.

---

<div class="post-metadata">

### Author: ![anon60034542](https://avatars.discourse-cdn.com/v4/letter/a/90ced4/32.png) [@anon60034542](https://discourse.julialang.org/u/anon60034542)
#### Post date: [May 4, 2021, 3:09pm UTC](https://discourse.julialang.org/t/do-type-annotations-help-julia-determine-which-method-to-call/60476/4 "2021-05-04T15:09:18Z")

</div>

I think I have a misunderstanding of the [documentation](https://docs.julialang.org/en/v1/manual/methods/).

> The most specific method definition matching the number and types of the arguments will be executed when the function is applied.

When checking for the type of arguments, I always assumed Julia will start with what it knows:

- We can’t use length to determine what method to call, because both methods require two arguments.

- The first method call to `do_work()` was given an `Int32` as the first argument.

None of the methods have `Int32` as the first argument, so we move up to `Signed`, `Integer`, etc… until it hits the final type, `Number`. Both methods take `Number`, so it moves to the second argument, `Float32`, no method takes a `Float32`, moving up, we check if any method takes `AbstractFloat`, which the second method does, so that method is called.

In other words, how does Julia match `Float32` with `AbstractFloat`? Does it move up the hierarchy until it finds the closest match?

---

<div class="post-metadata">

### Author: ![lhnguyen-vn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lhnguyen-vn/32/15449_2.png) [@lhnguyen-vn](https://discourse.julialang.org/u/lhnguyen-vn)
#### Post date: [May 4, 2021, 3:59pm UTC](https://discourse.julialang.org/t/do-type-annotations-help-julia-determine-which-method-to-call/60476/5 "2021-05-04T15:59:23Z")

</div>

Internally, there’s a `do_work` method table that is sorted by specificity, so any `do_work` dispatch only needs to provide the call signature and performs an O(n) search through the method table. The first method to match (and therefore the most specific) is `do_work(::Number, ::AbstractFloat)`, so Julia simply specializes on that one.  
But you’re not entirely wrong! Sorting methods by specificity and matching the call signatures both depend on an efficient [subtyping algorithm](https://github.com/JuliaLang/julia/blob/master/src/subtype.c), which you can peruse yourself if you’re well-versed with C. To juggle with `Union`s and `UnionAll`s, invariant parametric types and covariant tuple types, it is of course a lot more complicated than only traversing the type hierarchy, but a part of the process indeed does just that to incorporate subtyping relations declared by the user.
