# When should one type annotate a function signature?

**URL:** <https://discourse.julialang.org/t/when-should-one-type-annotate-a-function-signature/115019>\
**Category:** New to Julia\
**Tags:** question\
**Created:** [May 31, 2024, 4:31pm UTC](https://discourse.julialang.org/t/when-should-one-type-annotate-a-function-signature/115019 "2024-05-31T16:31:00Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ujjwal\_Panda](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ujjwal_panda/32/34628_2.png) [@Ujjwal\_Panda](https://discourse.julialang.org/u/Ujjwal_Panda)\
**Post date:** [May 31, 2024, 4:31pm UTC](https://discourse.julialang.org/t/when-should-one-type-annotate-a-function-signature/115019/1 "2024-05-31T16:31:01Z")

</div>

When developing a package, what is the convention when it comes to type annotating a function’s arguments? For instance, say I have a function that takes in three arguments, like so:

```julia
function f(a, b, c)
    @. a * b + c
end

```

and say that I always intend for `a` to be a `Vector`, and `b` and `c` to be real numbers. Then, should I type annotate the function signature like so:

```julia
function f(a::AbstractVector, b::Real, c::Real)
    @. a + b * c
end

```

or should I only do so when I intend to write different methods for `Vector`s and `Matrix`s, and want to use multiple dispatch to do that? Does type annotating a function’s signature help documentation, or should it be only used for dispatching on a function’s arguments?

---

<div class="post-metadata">

**Author:** ![Satvik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/satvik/32/20486_2.png) [@Satvik](https://discourse.julialang.org/u/Satvik)\
**Post date:** [May 31, 2024, 5:54pm UTC](https://discourse.julialang.org/t/when-should-one-type-annotate-a-function-signature/115019/2 "2024-05-31T17:54:20Z")

</div>

With libraries, I would generally lean towards Abstract annotations, or no annotations if nothing sufficiently abstract exists. I wouldn’t typically use a `AbstractVector` annotation, because a lot of code that works with `Vector` works with other collections like `Set`, and there’s no way to annotate general Iterables. But I would use `Number`, which is pretty general.

For applications, I’ll generally be a lot more specific, because the odds of someone wanting to use the code in a different way are much smaller, and the users of the code are my coworkers so it’s easier to change if needed.

Types are great documentation IMO, and definitely worth using that way in applications. My coworkers and I find it much easier to debug code with consistent annotations.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [May 31, 2024, 10:11pm UTC](https://discourse.julialang.org/t/when-should-one-type-annotate-a-function-signature/115019/3 "2024-05-31T22:11:22Z")

</div>

> [@Ujjwal\_Panda](#):
>
> Does type annotating a function’s signature help documentation, or should it be only used for dispatching on a function’s arguments?

See also the discussion of [argument-type declarations](https://docs.julialang.org/en/v1/manual/functions/#Argument-type-declarations) in the Julia manual, which discusses the utility (but not necessity) of declarations for clarity and correctness purposes, in addition to dispatch.

---

<div class="post-metadata">

**Author:** ![mrufsvold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mrufsvold/32/31600_2.png) [@mrufsvold](https://discourse.julialang.org/u/mrufsvold)\
**Post date:** [May 31, 2024, 11:12pm UTC](https://discourse.julialang.org/t/when-should-one-type-annotate-a-function-signature/115019/4 "2024-05-31T23:12:10Z")

</div>

With regard to your question about docs: Documenter.jl doesn’t pick up type annotations as far as I’m aware – just whatever you write in your docstring. That said, of someone calls `methods(f)` on your function, they will see it printed out with the type annotations.

And if they go to read your source code, it will help them understand the meaning of your arguments. That’s part of the reason I’m working on DuckTypes.jl. I want to be able to annotate arguments with their meaning without being bound to the type lattice.

---

<div class="post-metadata">

**Author:** ![Ujjwal\_Panda](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ujjwal_panda/32/34628_2.png) [@Ujjwal\_Panda](https://discourse.julialang.org/u/Ujjwal_Panda)\
**Post date:** [June 11, 2024, 2:11pm UTC](https://discourse.julialang.org/t/when-should-one-type-annotate-a-function-signature/115019/5 "2024-06-11T14:11:05Z")

</div>

That is how I have been using them till now, since using anything not sufficiently abstract will overspecialise the function. I am mostly writing libraries for now, hence I was not sure if using abstract annotations like `AbstractVector` and `Real` was alright or not. This clears it up a bit though. Thanks!

---

<div class="post-metadata">

**Author:** ![Ujjwal\_Panda](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ujjwal_panda/32/34628_2.png) [@Ujjwal\_Panda](https://discourse.julialang.org/u/Ujjwal_Panda)\
**Post date:** [June 11, 2024, 2:13pm UTC](https://discourse.julialang.org/t/when-should-one-type-annotate-a-function-signature/115019/6 "2024-06-11T14:13:23Z")

</div>

Thanks for sharing this @stevengj!I was a bit concerned about a prospective performance hit, but it is clearly written that there is no such hit in the docs:

> Argument-type declarations **normally have no impact on performance** : regardless of what argument types (if any) are declared, Julia compiles a specialized version of the function for the actual argument types passed by the caller. For example, calling `fib(1)` will trigger the compilation of specialized version of `fib` optimized specifically for `Int` arguments, which is then re-used if `fib(7)` or `fib(15)` are called.
