# On type annotations

**URL:** https://discourse.julialang.org/t/on-type-annotations/116305
**Category:** New to Julia
**Created:** [June 27, 2024, 1:13pm UTC](https://discourse.julialang.org/t/on-type-annotations/116305 "2024-06-27T13:13:24Z")
**Posts on this page:** 9
**Page:** 5

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [July 3, 2024, 10:03am UTC](https://discourse.julialang.org/t/on-type-annotations/116305/82 "2024-07-03T10:03:20Z")

</div>

To be absolutely clear, erroring at declaring another local variable of the same name does not involve the annotations at all:

```julia
julia> function foo(x)
        local x
       end
ERROR: syntax: local variable name "x" conflicts with an argument

```

> [@Matthijs\_1971](#):
>
> I did not expect this. I wonder if this is documented and desired Julia behavior

It’s very clearly documented that argument annotations serve [multiple dispatch](https://docs.julialang.org/en/v1/manual/methods/). Nowhere does it say that it restricts the type of instances assigned to a variable. I would argue that would be needlessly restrictive. Say you have a function `foo` that takes in either a `x::Int` or `x::Float64`, and `x` could switch types in the body `x = bar()::Union{Int, Float64}`. However, you need to dispatch to separate methods depending on what type the input `x` is. If the argument annotation restricted `x`’s type, it’s impossible to pull this off.

---

<div class="post-metadata">

### Author: ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)
#### Post date: [July 3, 2024, 10:11am UTC](https://discourse.julialang.org/t/on-type-annotations/116305/83 "2024-07-03T10:11:10Z")

</div>

> [@Matthijs\_1971](#):
>
> I wonder if this is documented and desired Julia behavior or a bug in the language that can be fixed now it is discovered.

Regardless whether it’s considered a bug it would be quite breaking to change and not really an option before 2.0. It could be a candidate for the mechanism proposed in [Add `strict` mechanism for opting into stricter subsets of the language · Issue #54903 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/54903) though.

---

<div class="post-metadata">

### Author: ![Eben60](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/eben60/32/13475_2.png) [@Eben60](https://discourse.julialang.org/u/Eben60)
#### Post date: [July 3, 2024, 11:13am UTC](https://discourse.julialang.org/t/on-type-annotations/116305/84 "2024-07-03T11:13:24Z")

</div>

> [@stephancb](#):
>
> ```julia
> function distance_to_target_nota(t) # no type annotations
> c = 299792458e0 # speed of light
> 
> ```

Actually, what is the reason of not allowing introducing `const` within a local scope like a function definition?

---

<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: [July 3, 2024, 11:55am UTC](https://discourse.julialang.org/t/on-type-annotations/116305/85 "2024-07-03T11:55:32Z")

</div>

> [@Eben60](#):
>
> Actually, what is the reason of not allowing introducing `const` within a local scope like a function definition?

See [implement local const · Issue #5148 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/5148)

---

<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: [July 5, 2024, 9:53am UTC](https://discourse.julialang.org/t/on-type-annotations/116305/86 "2024-07-05T09:53:07Z")

</div>

I’m prototyping a macro to get rid of the conversions here:

> [@A macro for removing calls to Base.convert: @noconvert](https://discourse.julialang.org/t/a-macro-for-removing-calls-to-base-convert-noconvert/116651):
>
> From the prior discussion [on type annotations](https://discourse.julialang.org/t/on-type-annotations/116305) I was wondering what a macro that removed all calls to Base.convert would look like. Here’s my prototype via Cassette.jl: using Cassette Cassette.@context NoConvertCtx; Cassette.overdub(context::NoConvertCtx, ::typeof(Base.convert), \_, x) = x macro noconvert(e) e.head == :function || error("Expression for @noconvert must be a full `function` definition") s = gensym("noconvert") fname = e.args[1].args[1] e2 = deepcopy(e) e2.args[…

```julia-repl
julia> @noconvert function foo(x::Number)
           let x::Int = x
               x
           end
       end
foo (generic function with 2 methods)

julia> foo(3)
3

julia> foo(3.0)
ERROR: TypeError: in typeassert, expected Int64, got a value of type Float64

julia> foo(3.5)
ERROR: TypeError: in typeassert, expected Int64, got a value of type Float64

```

The code generation looks pretty clean:

```julia-repl
julia> @code_llvm foo(3)
; @ none within `foo`
define i64 @julia_foo_1572(i64 signext %0) #0 {
top:
  ret i64 %0
}

julia> @code_llvm foo(3.0)
; @ none within `foo`
; Function Attrs: noreturn
define void @julia_foo_1574(double %0) #0 {
top:
  call void @j_overdub_1576(double %0) #6
  unreachable
}

```

---

<div class="post-metadata">

### Author: ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)
#### Post date: [March 8, 2025, 8:09pm UTC](https://discourse.julialang.org/t/on-type-annotations/116305/87 "2025-03-08T20:09:06Z")

</div>

> [@nsajko](#):
>
> **Never** put a type annotation on a variable. Put type assertions on expressions instead, e.g. on the RHS of an assignment.

An exception where variable type declarations are useful is when the variable will be captured by a closure and assigned to in the closure. Currently this leads to bad type inference for that variable unless it has a type declared.

---

<div class="post-metadata">

### Author: ![alfaromartino](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alfaromartino/32/52986_2.png) [@alfaromartino](https://discourse.julialang.org/u/alfaromartino)
#### Post date: [March 8, 2025, 8:36pm UTC](https://discourse.julialang.org/t/on-type-annotations/116305/88 "2025-03-08T20:36:08Z")

</div>

That doesn’t necessarily solve the problem.

```julia
function foo()
    x::Int64 = 1
    x = 1

    bar()::Int64 = x::Int64
    
    return bar()
end

@code_warntype foo() # type UNSTABLE

```

---

<div class="post-metadata">

### Author: ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)
#### Post date: [March 8, 2025, 9:23pm UTC](https://discourse.julialang.org/t/on-type-annotations/116305/89 "2025-03-08T21:23:10Z")

</div>

> [@alfaromartino](#):
>
> ```julia
> @code_warntype foo() # type UNSTABLE
> 
> ```

There’s some red in there, because of boxing, but the return type is precisely inferred due to the type declaration.

Compare `foo1` and `foo2`:

```julia
function foo1()
    x = 1
    x = 2
    function bar()
        x = 3
        x
    end
    bar()  
end
function foo2()
    x::Int = 1
    x = 2
    function bar()
        x = 3
        x
    end
    bar()
end
@code_warntype foo1()
@code_warntype foo2()

```

---

<div class="post-metadata">

### Author: ![alfaromartino](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alfaromartino/32/52986_2.png) [@alfaromartino](https://discourse.julialang.org/u/alfaromartino)
#### Post date: [March 8, 2025, 9:28pm UTC](https://discourse.julialang.org/t/on-type-annotations/116305/90 "2025-03-08T21:28:57Z")

</div>

Yes, my point is that closures can lead to unexpected behavior, and depending on where you add the type annotation, you don’t necessarily solve the problem. I was just adding a word of caution about using type annotations as a silver bullet for type inference in closures. But, yeah, in the example I provided, the issue won’t arise.

[Previous page](https://discourse.julialang.org/t/on-type-annotations/116305.md?page=4)
