diff options
Diffstat (limited to 'system/doc/reference_manual/typespec.xml')
-rw-r--r-- | system/doc/reference_manual/typespec.xml | 143 |
1 files changed, 74 insertions, 69 deletions
diff --git a/system/doc/reference_manual/typespec.xml b/system/doc/reference_manual/typespec.xml index 22627058c1..a0ea41cb3b 100644 --- a/system/doc/reference_manual/typespec.xml +++ b/system/doc/reference_manual/typespec.xml @@ -4,14 +4,14 @@ <chapter> <header> <copyright> - <year>2003</year><year>2015</year> + <year>2003</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - + http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software @@ -47,7 +47,7 @@ <list type="bulleted"> <item>To document function interfaces</item> <item>To provide more information for bug detection tools, - such as <c>Dialyzer</c></item> + such as Dialyzer</item> <item>To be exploited by documentation tools, such as EDoc, for generating program documentation of various forms</item> </list> @@ -63,13 +63,13 @@ Types consist of, and are built from, a set of predefined types, for example, <c>integer()</c>, <c>atom()</c>, and <c>pid()</c>. Predefined types represent a typically infinite set of Erlang terms that - belong to this type. For example, the type <c>atom()</c> stands for the + belong to this type. For example, the type <c>atom()</c> denotes the set of all Erlang atoms. </p> <p> For integers and atoms, it is allowed for singleton types; for example, the integers - <c>-1</c> and <c>42</c>, or the atoms <c>'foo'</c> and <c>'bar'</c>). + <c>-1</c> and <c>42</c>, or the atoms <c>'foo'</c> and <c>'bar'</c>. All other types are built using unions of either predefined types or singleton types. In a type union between a type and one @@ -131,16 +131,19 @@ | nonempty_improper_list(Type1, Type2) %% Type1 and Type2 as above | nonempty_list(Type) %% Proper non-empty list - Map :: map() %% stands for a map of any size - | #{} %% stands for a map of any size + Map :: map() %% denotes a map of any size + | #{} %% denotes the empty map | #{PairList} - Tuple :: tuple() %% stands for a tuple of any size + Tuple :: tuple() %% denotes a tuple of any size | {} | {TList} - PairList :: Type => Type - | Type => Type, PairList + PairList :: Pair + | Pair, PairList + + Pair :: Type := Type %% denotes a mandatory pair + | Type => Type %% denotes an optional pair TList :: Type | Type, TList @@ -148,9 +151,9 @@ Union :: Type1 | Type2 ]]></pre> <p> - The general form of bitstrings is <c><<_:M, _:_*N>></c>, + The general form of bit strings is <c><<_:M, _:_*N>></c>, where <c>M</c> and <c>N</c> are positive integers. It denotes a - bitstring that is <c>M + (k*N)</c> bits long (that is, a bitstring that + bit string that is <c>M + (k*N)</c> bits long (that is, a bit string that starts with <c>M</c> bits and continues with <c>k</c> segments of <c>N</c> bits each, where <c>k</c> is also a positive integer). The notations <c><<_:_*N>></c>, <c><<_:M>></c>, @@ -158,7 +161,7 @@ that <c>M</c> or <c>N</c>, or both, are zero. </p> <p> - Because lists are commonly used, they have shorthand type notations. + Because lists are commonly used, they have shorthand type notations. The types <c>list(T)</c> and <c>nonempty_list(T)</c> have the shorthands <c>[T]</c> and <c>[T,...]</c>, respectively. The only difference between the two shorthands is that <c>[T]</c> can be an @@ -166,12 +169,27 @@ </p> <p> Notice that the shorthand for <c>list()</c>, that is, the list of - elements of unknown type, is <c>[_]</c> (or <c>[any()]</c>), not <c>[]</c>. + elements of unknown type, is <c>[_]</c> (or <c>[any()]</c>), not <c>[]</c>. The notation <c>[]</c> specifies the singleton type for the empty list. </p> <p> - For convenience, the following types are also built-in. - They can be thought as predefined aliases for the type unions also shown in + The general form of maps is <c>#{PairList}</c>. The key types in + <c>PairList</c> are allowed to overlap, and if they do, the + leftmost pair takes precedence. A map pair has a key in + <c>PairList</c> if it belongs to this type. A <c>PairList</c> may contain + both 'mandatory' and 'optional' pairs where 'mandatory' denotes that + a key type, and its associated value type, must be present. + In the case of an 'optional' pair it is not required for the key type to + be present. + </p> + <p> + Notice that the syntactic representation of <c>map()</c> is + <c>#{any() => any()}</c> (or <c>#{_ => _}</c>), not <c>#{}</c>. + The notation <c>#{}</c> specifies the singleton type for the empty map. + </p> + <p> + For convenience, the following types are also built-in. + They can be thought as predefined aliases for the type unions also shown in the table. </p> <table> @@ -187,37 +205,37 @@ <row> <cell><c>bitstring()</c></cell><cell><c><<_:_*1>></c></cell> </row> - <row> + <row> <cell><c>boolean()</c></cell><cell><c>'false' | 'true'</c></cell> </row> - <row> + <row> <cell><c>byte()</c></cell><cell><c>0..255</c></cell> </row> <row> <cell><c>char()</c></cell><cell><c>0..16#10ffff</c></cell> </row> - <row> + <row> <cell><c>nil()</c></cell><cell><c>[]</c></cell> </row> <row> <cell><c>number()</c></cell><cell><c>integer() | float()</c></cell> </row> - <row> + <row> <cell><c>list()</c></cell><cell><c>[any()]</c></cell> </row> - <row> + <row> <cell><c>maybe_improper_list()</c></cell><cell><c>maybe_improper_list(any(), any())</c></cell> </row> - <row> + <row> <cell><c>nonempty_list()</c></cell><cell><c>nonempty_list(any())</c></cell> </row> <row> <cell><c>string()</c></cell><cell><c>[char()]</c></cell> </row> - <row> + <row> <cell><c>nonempty_string()</c></cell><cell><c>[char(),...]</c></cell> </row> - <row> + <row> <cell><c>iodata()</c></cell><cell><c>iolist() | binary()</c></cell> </row> <row> @@ -229,7 +247,7 @@ <row> <cell><c>module()</c></cell><cell><c>atom()</c></cell> </row> - <row> + <row> <cell><c>mfa()</c></cell><cell><c>{module(),atom(),arity()}</c></cell> </row> <row> @@ -245,7 +263,7 @@ <cell><c>timeout()</c></cell><cell><c>'infinity' | non_neg_integer()</c></cell> </row> <row> - <cell><c>no_return()</c></cell><cell><c>none()</c></cell> + <cell><c>no_return()</c></cell><cell><c>none()</c></cell> </row> <tcaption>Built-in types, predefined aliases</tcaption> </table> @@ -270,11 +288,11 @@ </row> <tcaption>Additional built-in types</tcaption> </table> - + <p> Users are not allowed to define types with the same names as the predefined or built-in ones. This is checked by the compiler and - its violation results in a compilation error. + its violation results in a compilation error. </p> <note> <p> @@ -302,12 +320,6 @@ This is described in <seealso marker="#typeinrecords"> Type Information in Record Declarations</seealso>. </p> - <note> - <p>Map types, both <c>map()</c> and <c>#{...}</c>, - are considered experimental during OTP 17.</p> - <p>No type information of maps pairs, only the containing map types, - are used by Dialyzer in OTP 17.</p> - </note> </section> <section> @@ -386,13 +398,13 @@ <pre> -record(rec, {field1 :: Type1, field2, field3 :: Type3}).</pre> <p> - For fields without type annotations, their type defaults to any(). + For fields without type annotations, their type defaults to any(). That is, the previous example is a shorthand for the following: </p> <pre> -record(rec, {field1 :: Type1, field2 :: any(), field3 :: Type3}).</pre> <p> - In the presence of initial values for fields, + In the presence of initial values for fields, the type must be declared after the initialization, as follows: </p> <pre> @@ -401,11 +413,13 @@ The initial values for fields are to be compatible with (that is, a member of) the corresponding types. This is checked by the compiler and results in a compilation error - if a violation is detected. For fields without initial values, - the singleton type <c>'undefined'</c> is added to all declared types. - In other words, the following two record declarations have identical - effects: + if a violation is detected. </p> + <note> + <p>Before Erlang/OTP 19, for fields without initial values, + the singleton type <c>'undefined'</c> was added to all declared types. + In other words, the following two record declarations had identical + effects:</p> <pre> -record(rec, {f1 = 42 :: integer(), f2 :: float(), @@ -415,26 +429,27 @@ f2 :: 'undefined' | float(), f3 :: 'undefined' | 'a' | 'b'}).</pre> <p> - For this reason, it is recommended that records contain initializers, - whenever possible. + This is no longer the case. If you require <c>'undefined'</c> in your record field + type, you must explicitly add it to the typespec, as in the 2nd example. </p> + </note> <p> - Any record, containing type information or not, once defined, + Any record, containing type information or not, once defined, can be used as a type using the following syntax: </p> <pre> #rec{}</pre> <p> - In addition, the record fields can be further specified when using + In addition, the record fields can be further specified when using a record type by adding type information about the field as follows: </p> <pre> #rec{some_field :: Type}</pre> <p> - Any unspecified fields are assumed to have the type in the original + Any unspecified fields are assumed to have the type in the original record declaration. </p> </section> - + <section> <title>Specifications for Functions</title> <p> @@ -448,9 +463,9 @@ else a compilation error occurs. </p> <p> - This form can also be used in header files (.hrl) to declare type - information for exported functions. - Then these header files can be included in files that (implicitly or + This form can also be used in header files (.hrl) to declare type + information for exported functions. + Then these header files can be included in files that (implicitly or explicitly) import these functions. </p> <p> @@ -464,14 +479,14 @@ <pre> -spec Function(ArgName1 :: Type1, ..., ArgNameN :: TypeN) -> RT.</pre> <p> - A function specification can be overloaded. + A function specification can be overloaded. That is, it can have several types, separated by a semicolon (<c>;</c>): </p> <pre> -spec foo(T1, T2) -> T3 ; (T4, T5) -> T6.</pre> <p> - A current restriction, which currently results in a warning + A current restriction, which currently results in a warning (not an error) by the compiler, is that the domains of the argument types cannot overlap. For example, the following specification results in a warning: @@ -480,9 +495,9 @@ -spec foo(pos_integer()) -> pos_integer() ; (integer()) -> integer().</pre> <p> - Type variables can be used in specifications to specify relations for - the input and output arguments of a function. - For example, the following specification defines the type of a + Type variables can be used in specifications to specify relations for + the input and output arguments of a function. + For example, the following specification defines the type of a polymorphic identity function: </p> <pre> @@ -495,7 +510,8 @@ </p> <pre> -spec id(X) -> X when X :: tuple().</pre> <p> - Currently, the <c>::</c> constraint (read as <c>is_subtype</c>) is + Currently, the <c>::</c> constraint + (read as «is a subtype of») is the only guard constraint that can be used in the <c>'when'</c> part of a <c>'-spec'</c> attribute. </p> @@ -513,7 +529,7 @@ <em>the same</em> tuple. </p> <p> - However, it is up to the tools that process the specificationss + However, it is up to the tools that process the specifications to choose whether to take this extra information into account or not. </p> @@ -529,19 +545,9 @@ <pre> -spec foo({X, integer()}) -> X when X :: atom() ; ([Y]) -> Y when Y :: number().</pre> - <note> - <p> - For backwards compatibility the following form is also allowed: - </p> - <pre> -spec id(X) -> X when is_subtype(X, tuple()).</pre> - <p> - but its use is discouraged. It will be removed in a future - Erlang/OTP release. - </p> - </note> <p> - Some functions in Erlang are not meant to return; - either because they define servers or because they are used to + Some functions in Erlang are not meant to return; + either because they define servers or because they are used to throw exceptions, as in the following function: </p> <pre> my_error(Err) -> erlang:throw({error, Err}).</pre> @@ -553,4 +559,3 @@ <pre> -spec my_error(term()) -> no_return().</pre> </section> </chapter> - |