Purposes of explicit type annotations

From the manual:

Adding [type] annotations serves three primary purposes: to take advantage of Julia’s powerful multiple-dispatch mechanism, to improve human readability, and to catch programmer errors.

I’m curious why memory and computational efficiency is not listed there. For example, having image data represented by a default Int64 pixels would be a huge memory waste and incur significant performance penalty in case where UInt8 would be sufficient.

1 Like

IIRC, this is talking about type annotations to function arguments where this isn’t a concern, not types. That said, i may be wrong. Where in the docs is this?

Chapter 18, Types, at the beginning (3rd paragraph). My understanding is that it applies to all uses of explicit typing.

On the third reading I can see that efficiency was mentioned a bit earlier:

Julia’s type system is dynamic, but gains some of the advantages of static type systems by making it possible to indicate that certain values are of specific types. This can be of great assistance in generating efficient code

Maybe the sentence I quoted should be changed to:

Adding [type] annotations to functions serves three primary purposes: to take advantage of Julia’s powerful multiple-dispatch mechanism, to improve human readability, and to catch programmer errors.

1 Like

While type annotations can achieve higher efficiency, its not guaranteed to. Its also possible to decrease efficiency with annotations. Perhaps by using types that overly large.

Sure, but that’s not what’s being discussed in that section. Including a few more lines of context:

Thus, one can write many useful Julia functions without ever explicitly using types. When additional expressiveness is needed, however, it is easy to gradually introduce explicit type annotations into previously “untyped” code. Adding annotations serves three primary purposes: to take advantage of Julia’s powerful multiple-dispatch mechanism, to improve human readability, and to catch programmer errors.

The point being made here is that the functions f(x::Vector{Int}) and g(x::Vector{<:Integer}) and h(x::AbstractVector) and k(x) will all give the same performance (for the same input). The fact that a function has a type annotation on its input is useful as a way to control multiple dispatch or signal to a user what kind of data they should provide, but it’s not necessary for performance in Julia.

Another way of putting this is that the performance of a function does depend on the values you provide to it (as in the Int vs UInt8 example you mention), but it generally does not depend on whether or not you provided a type annotation to its arguments when you defined that function.

8 Likes

It wasn’t clear to me on the first two readings. Perhaps making it explicit, would help the next reader: Adding type annotations to function parameters serves three primary purposes…

What is a case where performance of a function does depend on type annotation of its parameters?

https://docs.julialang.org/en/v1.6-dev/manual/performance-tips/#Be-aware-of-when-Julia-avoids-specializing-1

3 Likes