1
<?xml version="1.0" encoding="latin1" ?>
2
<!DOCTYPE chapter SYSTEM "chapter.dtd">
7
<year>2003</year><year>2009</year>
8
<holder>Ericsson AB. All Rights Reserved.</holder>
11
The contents of this file are subject to the Erlang Public License,
12
Version 1.1, (the "License"); you may not use this file except in
13
compliance with the License. You should have received a copy of the
14
Erlang Public License along with this software. If not, it can be
15
retrieved online at http://www.erlang.org/.
17
Software distributed under the License is distributed on an "AS IS"
18
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
19
the License for the specific language governing rights and limitations
24
<title>Types and Function Specifications</title>
25
<prepared>Kostis Sagonas, Tobias Lindahl, Kenneth Lundin</prepared>
29
<file>typespec.xml</file>
33
<title>Introduction of Types</title>
35
Although Erlang is a dynamically typed language this section describes
36
an extension to the Erlang language for declaring sets of Erlang terms
37
to form a particular type, effectively forming a specific sub-type of the
38
set of all Erlang terms.
41
Subsequently, these types can be used to specify types of record fields
42
and the argument and return types of functions.
45
Type information can be used to document function interfaces,
46
provide more information for bug detection tools such as <c>Dialyzer</c>,
47
and can be exploited by documentation tools such as <c>Edoc</c> for
48
generating program documentation of various forms.
49
It is expected that the type language described in this document will
50
supersede and replace the purely comment-based <c>@type</c> and
51
<c>@spec</c> declarations used by <c>Edoc</c>.
54
The syntax and semantics described here is still preliminary and might be
55
slightly changed and extended before it becomes officially supported.
56
The plan is that this will happen in R14B.
60
<marker id="syntax"></marker>
61
<title>Types and their Syntax</title>
63
Types describe sets of Erlang terms.
64
Types consist and are built from a set of predefined types (e.g. <c>integer()</c>,
65
<c>atom()</c>, <c>pid()</c>, ...) described below.
66
Predefined types represent a typically infinite set of Erlang terms which
68
For example, the type <c>atom()</c> stands for the set of all Erlang atoms.
71
For integers and atoms, we allow for singleton types (e.g. the integers <c>-1</c>
72
and <c>42</c> or the atoms <c>'foo'</c> and <c>'bar'</c>).
74
All other types are built using unions of either predefined types or singleton
75
types. In a type union between a type and one of its sub-types the sub-type is
76
absorbed by the super-type and the union is subsequently treated as if the
77
sub-type was not a constituent of the union. For example, the type union:
80
atom() | 'bar' | integer() | 42</pre>
82
describes the same set of terms as the type union:
85
atom() | integer()</pre>
87
Because of sub-type relations that exist between types, types form a lattice
88
where the topmost element, any(), denotes the set of all Erlang terms and
89
the bottom-most element, none(), denotes the empty set of terms.
92
The set of predefined types and the syntax for types is given below:
95
Type :: any() %% The top type, the set of all Erlang terms.
96
| none() %% The bottom type, contains no terms.
109
| UserDefined %% described in Section 2
111
Union :: Type1 | Type2
114
| Erlang_Atom %% 'foo', 'bar', ...
116
Binary :: binary() %% <<_:_ * 8>>
118
| <<_:Erlang_Integer>> %% Base size
119
| <<_:_*Erlang_Integer>> %% Unit size
120
| <<_:Erlang_Integer, _:_*Erlang_Integer>>
122
Fun :: fun() %% any function
123
| fun((...) -> Type) %% any arity, returning Type
125
| fun((TList) -> Type)
128
| Erlang_Integer %% ..., -1, 0, 1, ... 42 ...
129
| Erlang_Integer..Erlang_Integer %% specifies an integer range
131
List :: list(Type) %% Proper list ([]-terminated)
132
| improper_list(Type1, Type2) %% Type1=contents, Type2=termination
133
| maybe_improper_list(Type1, Type2) %% Type1 and Type2 as above
135
Tuple :: tuple() %% stands for a tuple of any size
143
Because lists are commonly used, they have shorthand type notations.
144
The type <c>list(T)</c> has the shorthand <c>[T]</c>. The shorthand <c>[T,...]</c> stands for
145
the set of non-empty proper lists whose elements are of type <c>T</c>.
146
The only difference between the two shorthands is that <c>[T]</c> may be an
147
empty list but <c>[T,...]</c> may not.
150
Notice that the shorthand for <c>list()</c>, i.e. the list of elements of unknown type,
151
is <c>[_]</c> (or <c>[any()]</c>), not <c>[]</c>.
152
The notation <c>[]</c> specifies the singleton type for the empty list.
155
For convenience, the following types are also built-in.
156
They can be thought as predefined aliases for the type unions also shown in
157
the table. (Some type unions below slightly abuse the syntax of types.)
161
<cell><b>Built-in type</b></cell><cell><b>Stands for</b></cell>
164
<cell><c>term()</c></cell><cell><c>any()</c></cell>
167
<cell><c>bool()</c></cell><cell><c>'false' | 'true'</c></cell>
170
<cell><c>byte()</c></cell><cell><c>0..255</c></cell>
173
<cell><c>char()</c></cell><cell><c>0..16#10ffff</c></cell>
176
<cell><c>non_neg_integer()</c></cell><cell><c>0..</c></cell>
179
<cell><c>pos_integer()</c></cell><cell><c>1..</c></cell>
182
<cell><c>neg_integer()</c></cell><cell><c>..-1</c></cell>
185
<cell><c>number()</c></cell><cell><c>integer() | float()</c></cell>
188
<cell><c>list()</c></cell><cell><c>[any()]</c></cell>
191
<cell><c>maybe_improper_list()</c></cell><cell><c>maybe_improper_list(any(), any())</c></cell>
194
<cell><c>maybe_improper_list(T)</c></cell><cell><c>maybe_improper_list(T, any())</c></cell>
197
<cell><c>string()</c></cell><cell><c>[char()]</c></cell>
200
<cell><c>nonempty_string()</c></cell><cell><c>[char(),...]</c></cell>
203
<cell><c>iolist()</c></cell><cell><c>maybe_improper_list(
204
char() | binary() | iolist(), binary() | [])</c></cell>
207
<cell><c>module()</c></cell><cell><c>atom()</c></cell>
210
<cell><c>mfa()</c></cell><cell><c>{atom(),atom(),byte()}</c></cell>
213
<cell><c>node()</c></cell><cell><c>atom()</c></cell>
216
<cell><c>timeout()</c></cell><cell><c>'infinity' | non_neg_integer()</c></cell>
219
<cell><c>no_return()</c></cell><cell><c>none()</c></cell>
224
Users are not allowed to define types with the same names as the predefined or
226
This is checked by the compiler and its violation results in a compilation
228
(For bootstrapping purposes, it can also result to just a warning if this
229
involves a built-in type which has just been introduced.)
232
The following built-in list types also exist,
233
but they are expected to be rarely used. Hence, they have long names:
236
nonempty_maybe_improper_list(Type) :: nonempty_maybe_improper_list(Type, any())
237
nonempty_maybe_improper_list() :: nonempty_maybe_improper_list(any())
240
where the following two types
241
define the set of Erlang terms one would expect:
244
nonempty_improper_list(Type1, Type2)
245
nonempty_maybe_improper_list(Type1, Type2)
248
Also for convenience, we allow for record notation to be used.
249
Records are just shorthands for the corresponding tuples.
252
Record :: #Erlang_Atom{}
253
| #Erlang_Atom{Fields}
256
Records have been extended to possibly contain type information.
257
This is described in the sub-section <seealso marker="#typeinrecords">"Type information in record declarations"</seealso> below.
262
<title>Type declarations of user-defined types</title>
264
As seen, the basic syntax of a type is an atom followed by closed
265
parentheses. New types are declared using '-type' compiler attributes
269
-type my_type() :: Type.
272
where the type name is an atom (<c>'my_type'</c> in the above) followed by
273
parenthesis. Type is a type as defined in the previous section.
274
A current restriction is that Type can contain only predefined types
275
or user-defined types which have been previously defined.
276
This restriction is enforced by the compiler and results in a
277
compilation error. (A similar restriction currently exists for records).
280
This means that currently general recursive types cannot be defined.
281
Lifting this restriction is future work.
284
Type declarations can also be parameterized by including type variables
285
between the parentheses. The syntax of type variables is the same as
286
Erlang variables (starts with an upper case letter).
287
Naturally, these variables can - and should - appear on the RHS of the
288
definition. A concrete example appears below:
291
-type orddict(Key, Val) :: [{Key, Val}].
296
<marker id="typeinrecords"/>
299
Type information in record declarations
302
The types of record fields can be specified in the declaration of the
303
record. The syntax for this is:
306
-record(rec, {field1 :: Type1, field2, field3 :: Type3}).
309
For fields without type annotations, their type defaults to any().
310
I.e., the above is a shorthand for:
313
-record(rec, {field1 :: Type1, field2 :: any(), field3 :: Type3}).
316
In the presence of initial values for fields,
317
the type must be declared after the initialization as in the following:
320
-record(rec, {field1 = [] :: Type1, field2, field3 = 42 :: Type3}).
323
Naturally, the initial values for fields should be compatible
324
with (i.e. a member of) the corresponding types.
325
This is checked by the compiler and results in a compilation error
326
if a violation is detected. For fields without initial values,
327
the singleton type <c>'undefined'</c> is added to all declared types.
328
In other words, the following two record declarations have identical
332
-record(rec, {f1 = 42 :: integer(),
336
-record(rec, {f1 = 42 :: integer(),
337
f2 :: 'undefined' | float(),
338
f3 :: 'undefined' | 'a' | 'b').
341
For this reason, it is recommended that records contain initializers,
345
Any record, containing type information or not, once defined,
346
can be used as a type using the syntax:
352
In addition, the record fields can be further specified when using
353
a record type by adding type information about the field in the following
357
#rec{some_field :: Type}
360
Any unspecified fields are assumed to have the type in the original
366
<title>Specifications (contracts) for functions</title>
368
A contract (or specification) for a function is given using the new
369
compiler attribute <c>'-spec'</c>. The basic format is as follows:
372
-spec Module:Function(ArgType1, ..., ArgTypeN) -> ReturnType.
375
The arity of the function has to match the number of arguments,
376
or else a compilation error occurs.
379
This form can also be used in header files (.hrl) to declare type
380
information for exported functions.
381
Then these header files can be included in files that (implicitly or
382
explicitly) import these functions.
385
For most uses within a given module, the following shorthand is allowed:
388
-spec Function(ArgType1, ..., ArgTypeN) -> ReturnType.
391
Also, for documentation purposes, argument names can be given:
394
-spec Function(ArgName1 :: Type1, ..., ArgNameN :: TypeN) -> RT.
397
A function specification can be overloaded.
398
That is, it can have several types, separated by a semicolon (<c>;</c>):
401
-spec foo(T1, T2) -> T3
405
A current restriction, which currently results in a warning
406
(OBS: not an error) by the compiler, is that the domains of the argument
407
types cannot be overlapping.
408
For example, the following specification results in a warning:
411
-spec foo(pos_integer()) -> pos_integer()
412
; (integer()) -> integer().
415
Type variables can be used in specifications to specify relations for
416
the input and output arguments of a function.
417
For example, the following specification defines the type of a
418
polymorphic identity function:
424
However, note that the above specification does not restrict the input
425
and output type in any way.
426
We can constrain these types by guard-like subtype constraints:
429
-spec id(X) -> X when is_subtype(X, tuple()).
432
and provide bounded quantification. Currently,
433
the <c>is_subtype/2</c> guard is the only guard which can
434
be used in a <c>'-spec'</c> attribute.
437
The scope of an <c>is_subtype/2</c> constraint is the
438
<c>(...) -> RetType</c>
439
specification after which it appears. To avoid confusion,
440
we suggest that different variables are used in different constituents of
441
an overloaded contract as in the example below:
444
-spec foo({X, integer()}) -> X when is_subtype(X, atom())
445
; ([Y]) -> Y when is_subtype(Y, number()).
448
Some functions in Erlang are not meant to return;
449
either because they define servers or because they are used to
450
throw exceptions as the function below:
453
my_error(Err) -> erlang:throw({error, Err}).
456
For such functions we recommend the use of the special no_return()
457
type for their "return", via a contract of the form:
460
-spec my_error(term()) -> no_return().