# Basic question about different type annotations in function declarations

**URL:** <https://discourse.julialang.org/t/basic-question-about-different-type-annotations-in-function-declarations/29086>\
**Category:** Performance\
**Tags:** parametric-types\
**Created:** [September 23, 2019, 6:46pm UTC](https://discourse.julialang.org/t/basic-question-about-different-type-annotations-in-function-declarations/29086 "2019-09-23T18:46:58Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![SEA](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sea/32/8956_2.png) [@SEA](https://discourse.julialang.org/u/SEA)\
**Post date:** [September 23, 2019, 6:46pm UTC](https://discourse.julialang.org/t/basic-question-about-different-type-annotations-in-function-declarations/29086/1 "2019-09-23T18:46:58Z")

</div>

I wanted to clarify my understanding of the following ways of defining a function.

1. f(x) = …

2. f(x::T) where {T} = …

3. f(x::Any) = …

- Is it true that 1. and 2. are equivalent if there are no type restrictions in the UnionAll? That is, the function is specialized for every different concrete input type.

- Is it true that 3. is never specialized for a concrete type, but it is executed as if its argument is of type Any? I imagine this is important if one wants to limit excessive specializations for functions which do not benefit from it much.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [September 23, 2019, 7:56pm UTC](https://discourse.julialang.org/t/basic-question-about-different-type-annotations-in-function-declarations/29086/2 "2019-09-23T19:56:29Z")

</div>

There is no difference between those three, except that in 2. the type parameter `T` will be available inside the function body (you can anyway get that by calling `T = typeof(x)` later on.)

Each will be specialized every time. In order to avoid specialization, you can look at `@nospecialize`: [Essentials · The Julia Language](https://docs.julialang.org/en/v1/base/base/#Base.@nospecialize)

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [September 23, 2019, 7:56pm UTC](https://discourse.julialang.org/t/basic-question-about-different-type-annotations-in-function-declarations/29086/3 "2019-09-23T19:56:31Z")

</div>

> [@SEA](#):
>
> Is it true that 1. and 2. are equivalent if there are no type restrictions in the UnionAll? That is, the function is specialized for every different concrete input type.

Yes that is true.

> [@SEA](#):
>
> Is it true that 3. is never specialized for a concrete type, but it is executed as if its argument is of type Any? I imagine this is important if one wants to limit excessive specializations for functions which do not benefit from it much.

No that is not true. Julia will always specialize on the concrete type unless you use the `@nospecialize` macro.

---

<div class="post-metadata">

**Author:** ![SEA](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sea/32/8956_2.png) [@SEA](https://discourse.julialang.org/u/SEA)\
**Post date:** [September 23, 2019, 8:08pm UTC](https://discourse.julialang.org/t/basic-question-about-different-type-annotations-in-function-declarations/29086/4 "2019-09-23T20:08:30Z")

</div>

I see!

So this is different to the - in an abstract sense similar - struct declarations

1. struct A  
a::Any  
end

2. struct A{T}  
a::T  
end

Functions dealing with 1. won’t be able to specialize for a concrete field type, in contrast to 2. Correct?

---

<div class="post-metadata">

**Author:** ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)\
**Post date:** [September 23, 2019, 8:13pm UTC](https://discourse.julialang.org/t/basic-question-about-different-type-annotations-in-function-declarations/29086/5 "2019-09-23T20:13:09Z")

</div>

There is a subtle difference that 2 will force specialization, whereas the other two leave it to the compiler. At least this is how it used to be [Splatting arguments causes ~30x slow down - #2 by tim.holy](https://discourse.julialang.org/t/splatting-arguments-causes-30x-slow-down/16964/2).

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [September 23, 2019, 9:25pm UTC](https://discourse.julialang.org/t/basic-question-about-different-type-annotations-in-function-declarations/29086/6 "2019-09-23T21:25:18Z")

</div>

> [@SEA](#):
>
> So this is different to the - in an abstract sense similar - struct declarations

Yes.
