You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: lib/elixir/pages/Typespecs.md
+21-13Lines changed: 21 additions & 13 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,16 +1,24 @@
1
1
# Typespecs
2
2
3
-
Elixir comes with a notation for declaring types and specifications. Elixir is dynamically typed, and as such, typespecs are never used by the compiler to optimize or modify code. Still, using typespecs is useful as documentation and tools such as [Dialyzer](http://www.erlang.org/doc/man/dialyzer.html) can analyze code with typespecs to find bugs.
3
+
Elixir comes with a notation for declaring types and specifications. Elixir is a dynamically typed language, and as such, type specifications are never used by the compiler to optimize or modify code. Still, using type specifications is useful because
4
4
5
-
The attributes `@type`, `@opaque`, `@typep`, `@spec`, `@callback` and `@macrocallback` are the main mechanism for defining typespecs. See sub-sections "Defining a type" and "Defining a specification" below.
5
+
* they provide documentation (for example, tools such as [ExDoc](https://github.com/elixir-lang/ex_doc) show type specifications in the documentation)
6
+
* they're used by tools sych as [Dialyzer](http://www.erlang.org/doc/man/dialyzer.html), that can analyze code with typespec to find type inconsistencies and possible bugs
6
7
7
-
## Types and their syntax
8
+
Type specifications (sometimes referred to as *typespecs*) are defined in different contexts using the following attributes:
9
+
10
+
*`@type`
11
+
*`@opaque`
12
+
*`@typep`
13
+
*`@spec`
14
+
*`@callback`
15
+
*`@macrocallback`
8
16
9
-
The type syntax provided by Elixir is fairly similar to [the one in Erlang](http://www.erlang.org/doc/reference_manual/typespec.html).
17
+
See the "Defining a type" and "Defining a specification" sub-sections below for more information on defining types and typespecs.
10
18
11
-
Most of the built-in types provided in Erlang (for example, `pid()`) are expressed the same way: `pid()` or simply `pid`. Parameterized types are also supported (`list(integer)`) and so are remote types (`Enum.t`).
19
+
## Types and their syntax
12
20
13
-
Integers and atom literals are allowed as types (ex.`1`, `:atom` or `false`). All other types are built of unions of predefined types. Certain shorthands are allowed, such as `[...]`, `<<>>` and `{...}`.
21
+
The syntax Elixir provides for type specifications is similar to [the one in Erlang](http://www.erlang.org/doc/reference_manual/typespec.html). Most of the built-in types provided in Erlang (for example, `pid()`) are expressed in the same way: `pid()` (or simply `pid`). Parametrized types (such as `list(integer)`) are supported as well and so are remote types (such as `Enum.t`). Integers and atom literals are allowed as types (e.g.,`1`, `:atom`, or `false`). All other types are built out of unions of predefined types. Some shorthands are allowed, such as `[...]`, `<<>>`, and `{...}`.
14
22
15
23
### Basic types
16
24
@@ -78,7 +86,7 @@ The following literals are also supported in typespecs:
78
86
79
87
### Built-in types
80
88
81
-
These types are also provided by Elixir as shortcuts on top of the basic and literal types.
89
+
The following types are also provided by Elixir as shortcuts on top of the basic and literal types described above.
82
90
83
91
Built-in type | Defined as
84
92
:---------------------- | :---------
@@ -110,7 +118,7 @@ Built-in type | Defined as
110
118
111
119
### Remote types
112
120
113
-
Any module is also able to define its own type and the modules in Elixir are no exception. For example, a string is `String.t`, a range is `Range.t`, any enumerable can be `Enum.t` and so on.
121
+
Any module is also able to define its own types and the modules in Elixir are no exception. For example, the `Range` module defines a `t` type that represents a range: this type can be referred to as `Range.t`. In a similar fashion, a string is `String.t`, any enumerable can be `Enum.t`, and so on.
114
122
115
123
### Maps
116
124
@@ -122,13 +130,15 @@ Notice that the syntactic representation of `map()` is `%{...}` (or `%{optional(
122
130
123
131
## Defining a type
124
132
133
+
The `@type`, `@typep`, and `@opaque` module attributes can be used to define new types:
134
+
125
135
@type type_name :: type
126
136
@typep type_name :: type
127
137
@opaque type_name :: type
128
138
129
139
A type defined with `@typep` is private. An opaque type, defined with `@opaque` is a type where the internal structure of the type will not be visible, but the type is still public.
130
140
131
-
Types can be parameterized by defining variables as parameters, these variables can then be used to define the type.
141
+
Types can be parameterized by defining variables as parameters; these variables can then be used to define the type.
132
142
133
143
@type dict(key, value) :: [{key, value}]
134
144
@@ -148,17 +158,15 @@ Type variables with no restriction can also be defined.
148
158
149
159
@spec function(arg) :: [arg] when arg: var
150
160
151
-
You can also name your arguments in a typespec using `arg_name :: arg_type` syntax.
152
-
This is particularly useful as a way to differentiate multiple arguments
153
-
of the same type (or multiple elements of the same type in a type def):
161
+
You can also name your arguments in a typespec using `arg_name :: arg_type` syntax. This is particularly useful in documentation as a way to differentiate multiple arguments of the same type (or multiple elements of the same type in a type definition):
0 commit comments