Skip to content

Commit 259898f

Browse files
committed
docs: Clarify important points about parametric types
Closes JuliaLang#43811. - The intro section felt a bit long-winded, I've made some changes there first. - Clarify that `typeof` returns the concrete type - Rename Type Declarations section to Type Annotations, avoid confusion with Declaring Types section and distinguish use of "type declaration" to mean "declaring new types" - Removed some of the jargon and wikipedia links to make room for a brief alternative `Point{T1,T2}` demonstration. - Shifted some paragraphs around to reflect their importance, and changed the wording in some places. - Rename type declaration -> annotation in other places (docstrings/comments)
1 parent 816c6a2 commit 259898f

File tree

9 files changed

+135
-136
lines changed

9 files changed

+135
-136
lines changed

base/docs/basedocs.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -2569,7 +2569,7 @@ converted to type `T` by calling [`convert`](@ref).
25692569
In a method declaration, the syntax `function f(x)::T` causes any value returned by
25702570
the method to be converted to type `T`.
25712571
2572-
See the manual section on [Type Declarations](@ref).
2572+
See the manual section on [Type Annotations](@ref).
25732573
25742574
# Examples
25752575
```jldoctest

doc/src/index.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,13 @@ The most significant departures of Julia from typical dynamic languages are:
6464
* The core language imposes very little; Julia Base and the standard library are written in Julia itself, including
6565
primitive operations like integer arithmetic
6666
* A rich language of types for constructing and describing objects, that can also optionally be
67-
used to make type declarations
67+
used to write type annotations
6868
* The ability to define function behavior across many combinations of argument types via [multiple dispatch](https://en.wikipedia.org/wiki/Multiple_dispatch)
6969
* Automatic generation of efficient, specialized code for different argument types
7070
* Good performance, approaching that of statically-compiled languages like C
7171

7272
Although one sometimes speaks of dynamic languages as being "typeless", they are definitely not:
73-
every object, whether primitive or user-defined, has a type. The lack of type declarations in
73+
every object, whether primitive or user-defined, has a type. The lack of type annotations in
7474
most dynamic languages, however, means that one cannot instruct the compiler about the types of
7575
values, and often cannot explicitly talk about types at all. In static languages, on the other
7676
hand, while one can -- and usually must -- annotate types for the compiler, types exist only at

doc/src/manual/faq.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ julia> twothreearr()
359359
3
360360
```
361361

362-
## Types, type declarations, and constructors
362+
## Types, type annotations, and constructors
363363

364364
### [What does "type-stable" mean?](@id man-type-stability)
365365

doc/src/manual/functions.md

+7-7
Original file line numberDiff line numberDiff line change
@@ -63,20 +63,20 @@ are identical to the passed values. Modifications to mutable values (such as `Ar
6363
a function will be visible to the caller. This is the same behavior found in Scheme, most Lisps,
6464
Python, Ruby and Perl, among other dynamic languages.
6565

66-
## Argument-type declarations
66+
## Argument-type annotations
6767

68-
You can declare the types of function arguments by appending `::TypeName` to the argument name, as usual for [Type Declarations](@ref) in Julia.
68+
You can declare the types of function arguments by appending `::TypeName` to the argument name, as usual for [Type Annotations](@ref) in Julia.
6969
For example, the following function computes [Fibonacci numbers](https://en.wikipedia.org/wiki/Fibonacci_number) recursively:
7070
```
7171
fib(n::Integer) = n ≤ 2 ? one(n) : fib(n-1) + fib(n-2)
7272
```
7373
and the `::Integer` specification means that it will only be callable when `n` is a subtype of the [abstract](@ref man-abstract-types) `Integer` type.
7474

75-
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. (There are rare exceptions when an argument-type declaration can trigger additional compiler specializations; see: [Be aware of when Julia avoids specializing](@ref).) The most common reasons to declare argument types in Julia are, instead:
75+
Argument-type annotations **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. (There are rare exceptions when an argument-type annotation can trigger additional compiler specializations; see: [Be aware of when Julia avoids specializing](@ref).) The most common reasons to declare argument types in Julia are, instead:
7676

7777
* **Dispatch:** As explained in [Methods](@ref), you can have different versions ("methods") of a function for different argument types, in which case the argument types are used to determine which implementation is called for which arguments. For example, you might implement a completely different algorithm `fib(x::Number) = ...` that works for any `Number` type by using [Binet's formula](https://en.wikipedia.org/wiki/Fibonacci_number#Binet%27s_formula) to extend it to non-integer values.
78-
* **Correctness:** Type declarations can be useful if your function only returns correct results for certain argument types. For example, if we omitted argument types and wrote `fib(n) = n ≤ 2 ? one(n) : fib(n-1) + fib(n-2)`, then `fib(1.5)` would silently give us the nonsensical answer `1.0`.
79-
* **Clarity:** Type declarations can serve as a form of documentation about the expected arguments.
78+
* **Correctness:** Type annotations can be useful if your function only returns correct results for certain argument types. For example, if we omitted argument types and wrote `fib(n) = n ≤ 2 ? one(n) : fib(n-1) + fib(n-2)`, then `fib(1.5)` would silently give us the nonsensical answer `1.0`.
79+
* **Clarity:** Type annotations can serve as a form of documentation about the expected arguments.
8080

8181
However, it is a **common mistake to overly restrict the argument types**, which can unnecessarily limit the applicability of the function and prevent it from being re-used in circumstances you did not anticipate. For example, the `fib(n::Integer)` function above works equally well for `Int` arguments (machine integers) and `BigInt` arbitrary-precision integers (see [BigFloats and BigInts](@ref BigFloats-and-BigInts)), which is especially useful because Fibonacci numbers grow exponentially rapidly and will quickly overflow any fixed-precision type like `Int` (see [Overflow behavior](@ref)). If we had declared our function as `fib(n::Int)`, however, the application to `BigInt` would have been prevented for no reason. In general, you should use the most general applicable abstract types for arguments, and **when in doubt, omit the argument types**. You can always add argument-type specifications later if they become necessary, and you don't sacrifice performance or functionality by omitting them.
8282

@@ -161,9 +161,9 @@ Int8
161161
```
162162

163163
This function will always return an `Int8` regardless of the types of `x` and `y`.
164-
See [Type Declarations](@ref) for more on return types.
164+
See [Type Annotations](@ref) for more on return types.
165165

166-
Return type declarations are **rarely used** in Julia: in general, you should
166+
Return type annotations are **rarely used** in Julia: in general, you should
167167
instead write "type-stable" functions in which Julia's compiler can automatically
168168
infer the return type. For more information, see the [Performance Tips](@ref man-performance-tips) chapter.
169169

doc/src/manual/methods.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ which shows that `f` has two methods, one taking two `Float64` arguments and one
181181
of type `Number`. It also indicates the file and line number where the methods were defined: because
182182
these methods were defined at the REPL, we get the apparent line number `none:1`.
183183

184-
In the absence of a type declaration with `::`, the type of a method parameter is `Any` by default,
184+
In the absence of a type annotation with `::`, the type of a method parameter is `Any` by default,
185185
meaning that it is unconstrained since all values in Julia are instances of the abstract type
186186
`Any`. Thus, we can define a catch-all method for `f` like so:
187187

doc/src/manual/performance-tips.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -201,12 +201,12 @@ better than `IdDict{Type, Vector}`
201201

202202
See also the discussion under [Parametric Types](@ref).
203203

204-
## Type declarations
204+
## Type annotations
205205

206-
In many languages with optional type declarations, adding declarations is the principal way to
206+
In many languages with optional type annotations, adding declarations is the principal way to
207207
make code run faster. This is *not* the case in Julia. In Julia, the compiler generally knows
208208
the types of all function arguments, local variables, and expressions. However, there are a few
209-
specific instances where declarations are helpful.
209+
specific instances where annotations are helpful.
210210

211211
### Avoid fields with abstract type
212212

0 commit comments

Comments
 (0)