From 9fe8adf35c16ab5d4566b03f3b36863c90b5b6dd Mon Sep 17 00:00:00 2001
From: Hans Bolinder In Erlang 4.8/OTP R5A the syntax of Erlang tokens was extended to
+ Since Erlang 4.8/OTP R5A, the syntax of Erlang tokens is extended to
allow the use of the full ISO-8859-1 (Latin-1) character set. This
is noticeable in the following ways: In Erlang/OTP R16B the syntax of Erlang tokens was extended to
handle Unicode. The support is limited to
@@ -111,13 +111,13 @@
The Erlang source file The Erlang source file The following example selects UTF-8 as default encoding: The default encoding for Erlang source files was changed from
- Latin-1 to UTF-8 in Erlang OTP 17.0. The default encoding for Erlang source files is changed from
+ Latin-1 to UTF-8 since Erlang/OTP 17.0. How code is compiled and loaded is not a language issue, but
- is system dependent. This chapter describes compilation and
- code loading in Erlang/OTP with pointers to relevant parts of
+ is system-dependent. This section describes compilation and
+ code loading in Erlang/OTP with references to relevant parts of
the documentation. Erlang programs must be compiled to object code.
- The compiler can generate a new file which contains the object
- code. The current abstract machine which runs the object code is
+ The compiler can generate a new file that contains the object
+ code. The current abstract machine, which runs the object code, is
called BEAM, therefore the object files get the suffix
The compiler is located in the Kernel module The compiler is located in the module The Erlang shell understands the command There is also a module The compiler can also be accessed from the OS prompt, see
- There is also a module The compiler can also be accessed from the OS prompt, see the
+ The The object code must be loaded into the Erlang runtime
- system. This is handled by the code server, see
- The code server loads code according to a code loading strategy
+ system. This is handled by the code server, see the
+ The code server loads code according to a code loading strategy,
which is either interactive (default) or
- embedded. In interactive mode, code are searched for in
+ embedded. In interactive mode, code is searched for in
a code path and loaded when first referenced. In
- embedded mode, code is loaded at start-up according to a boot script. This is described in System Principles.
@@ -98,7 +98,7 @@
@@ -127,7 +127,7 @@
%% For this file we have chosen encoding = Latin-1
%% -*- coding: latin-1 -*-
-
compile:file(Module)
compile:file(Module, Options)
% erl -compile Module1...ModuleN
% erl -make
@@ -68,13 +72,17 @@ compile:file(Module, Options)
Both old and current code is valid, and may be evaluated +
Both old and current code is valid, and can be evaluated concurrently. Fully qualified function calls always refer to - current code. Old code may still be evaluated because of processes + current code. Old code can still be evaluated because of processes lingering in the old code.
-If a third instance of the module is loaded, the code server will - remove (purge) the old code and any processes lingering in it will - be terminated. Then the third instance becomes 'current' and +
If a third instance of the module is loaded, the code server + removes (purges) the old code and any processes lingering in it is + terminated. Then the third instance becomes 'current' and the previously current code becomes 'old'.
To change from old code to current code, a process must make a - fully qualified function call. Example:
+ fully qualified function call. +Example:
-module(m). -export([loop/0]). @@ -109,60 +118,62 @@ loop() -> loop() end.
To make the process change code, send the message
-
For code replacement of funs to work, the syntax
-
For code replacement of funs to work, use the syntax
+
The
The
Doing external call in on_load to the module itself
+ Doing external call in At module upgrade, other processes calling the module
- get suspended waiting for on_load to finish. This can be very bad
+ get suspended waiting for At module upgrade, no rollback is done if the on_load function fails.
- The system will be left in a bad limbo state without any working
+ At module upgrade, no rollback is done if the
+
The problems with module upgrade described above could be fixed in future - releases by changing the behaviour to not make the module reachable until - after the on_load function has successfully returned.
+The problems with module upgrade described above can be fixed in future
+ Erlang/OTP releases by changing the behaviour to not make the module reachable until
+ after the
The
The
Its syntax is as follows:
-on_load(Name/0).-
It is not necessary to export the function. It will be called in a - freshly spawned process (which will be terminated as soon as the function +
It is not necessary to export the function. It is called in a
+ freshly spawned process (which terminates as soon as the function
returns). The function must return
A process that calls any function in a module whose
In embedded mode, all modules will be loaded first and then - will all on_load functions be called. The system will be - terminated unless all of the on_load functions return +
In embedded mode, first all modules are loaded.
+ Then all
Example:
+Example:
-module(m). @@ -174,7 +185,7 @@ load_my_nifs() -> erlang:load_nif(NifPath, Info).
If the call to
Erlang provides a number of data types, which are listed in + this section.
Erlang provides a number of data types which are listed in this - chapter. A piece of data of any data type is called a - term.
+A piece of data of any data type is called a term.
Examples:
+Examples:
1> 42. 42 @@ -75,11 +76,11 @@Atom -An atom is a literal, a constant with name. An atom should be +
An atom is a literal, a constant with name. An atom is to be enclosed in single quotes (') if it does not begin with a lower-case letter or if it contains other characters than alphanumeric characters, underscore (_), or @.
-Examples:
+Examples:
hello phone_number @@ -90,11 +91,11 @@ phone_numberBit Strings and Binaries A bit string is used to store an area of untyped memory.
-Bit Strings are expressed using the +
Bit strings are expressed using the
-bit syntax .Bit Strings which consists of a number of bits which is evenly - divisible by eight are called Binaries
-Examples:
+Bit strings that consist of a number of bits that are evenly + divisible by eight, are called binaries
+Examples:
1> <<10,20>>. <<10,20>> @@ -102,12 +103,14 @@ phone_number <<"ABC">> 1> <<1:1,0:1>>. <<2:2>>-More examples can be found in Programming Examples.
+For more examples, + see
+ Programming Examples .@@ -116,34 +119,42 @@ phone_number Reference -A reference is a term which is unique in an Erlang runtime +
A reference is a term that is unique in an Erlang runtime system, created by calling
make_ref/0 .A fun is a functional object. Funs make it possible to create an anonymous function and pass the function itself -- not its name -- as argument to other functions.
-Example:
+Example:
1> Fun1 = fun (X) -> X+1 end. #Fun<erl_eval.6.39074546> 2> Fun1(2). 3-Read more about funs in
+Fun Expressions . More examples can be found in Programming - Examples.Read more about funs in
+ Fun Expressions . For more examples, see ++ Programming Examples .Port Identifier -A port identifier identifies an Erlang port.
+open_port/2 , - which is used to create ports, will return a value of this type.A port identifier identifies an Erlang port.
+
open_port/2 , which is used to create ports, returns + a value of this data type.Read more about ports in
Ports and Port Drivers .Pid -A process identifier, pid, identifies a process. -
+spawn/1,2,3,4 ,spawn_link/1,2,3,4 and -spawn_opt/4 , which are used to create processes, return - values of this type. Example:A process identifier, pid, identifies a process.
+The following BIFs, which are used to create processes, return + values of this data type:
++
+- +
spawn/1,2,3,4 - +
spawn_link/1,2,3,4 - +
spawn_opt/4 Example:
1> spawn(m, f, []). <0.51.0>-The BIF
+self() returns the pid of the calling process. - Example:In the following example, the BIF
self() returns + the pid of the calling process:-module(m). -export([loop/0]). @@ -166,14 +177,14 @@ who_are_youTuple -Compound data type with a fixed number of terms:
+A tuple is a compound data type with a fixed number of terms:
{Term1,...,TermN}Each term
Term in the tuple is called an element. The number of elements is said to be the size of the tuple.There exists a number of BIFs to manipulate tuples.
-Examples:
+Examples:
1> P = {adam,24,{july,29}}. {adam,24,{july,29}} @@ -191,7 +202,8 @@ adamMap -Compound data type with a variable number of key-value associations:
+A map is a compound data type with a variable number of + key-value associations:
#{Key1=>Value1,...,KeyN=>ValueN}Each key-value association in the map is called an @@ -199,7 +211,7 @@ adam called elements. The number of association pairs is said to be the size of the map.
There exists a number of BIFs to manipulate maps.
-Examples:
+Examples:
1> M1 = #{name=>adam,age=>24,date=>{july,29}}. #{age => 24,date => {july,29},name => adam} @@ -214,16 +226,18 @@ adam 6> map_size(#{}). 0A collection of maps processing functions can be found in - the STDLIB module
-. maps Read more about
+Maps .manual page + in STDLIB. + maps Read more about maps in
+ Map Expressions .- Maps are considered experimental during OTP 17.
+Maps are considered to be experimental during Erlang/OTP R17.
List -Compound data type with a variable number of terms.
+A list is a compound data type with a variable number of terms.
[Term1,...,TermN]Each term
Term in the list is called an @@ -231,20 +245,21 @@ adam the length of the list.Formally, a list is either the empty list
-[] or consists of a head (first element) and a tail - (remainder of the list) which is also a list. The latter can + (remainder of the list). + The tail is also a list. The latter can be expressed as[H|T] . The notation -[Term1,...,TermN] above is actually shorthand for +[Term1,...,TermN] above is equivalent with the list[Term1|[...|[TermN|[]]]] .Example:
-[] is a list, thus
+Example:
+- +
[] is a list, thus
[c|[]] is a list, thus
[b|[c|[]]] is a list, thus
-[a|[b|[c|[]]]] is a list, or in short[a,b,c] .[a|[b|[c|[]]]] is a list, or in short[a,b,c] +A list where the tail is a list is sometimes called a proper list. It is allowed to have a list where the tail is not a - list, for example
-[a|b] . However, this type of list is of + list, for example,[a|b] . However, this type of list is of little practical use.Examples:
+Examples:
1> L1 = [a,2,{c,4}]. [a,2,{c,4}] @@ -261,18 +276,19 @@ a 7> length([]). 0A collection of list processing functions can be found in - the STDLIB module
+ thelists .lists manual + page in STDLIB.String Strings are enclosed in double quotes ("), but is not a - data type in Erlang. Instead a string
"hello" is - shorthand for the list[$h,$e,$l,$l,$o] , that is + data type in Erlang. Instead, a string"hello" is + shorthand for the list[$h,$e,$l,$l,$o] , that is,[104,101,108,108,111] .Two adjacent string literals are concatenated into one. This is - done at compile-time and does not incur any runtime overhead. - Example:
+ done in the compilation, thus, does not incur any runtime overhead. +Example:
"string" "42"is equivalent to
@@ -284,12 +300,13 @@ aRecord A record is a data structure for storing a fixed number of elements. It has named fields and is similar to a struct in C. - However, record is not a true data type. Instead record + However, a record is not a true data type. Instead, record expressions are translated to tuple expressions during compilation. Therefore, record expressions are not understood by - the shell unless special actions are taken. See
-shell(3) - for details.Examples:
+ the shell unless special actions are taken. For details, see the +shell(3) manual + page in STDLIB). +Examples:
-module(person). -export([new/2]). @@ -303,14 +320,15 @@ new(Name, Age) -> {person,ernie,44}Read more about records in
+ found inRecords . More examples can be - found in Programming Examples.+ Programming Examples .Boolean There is no Boolean data type in Erlang. Instead the atoms
-true andfalse are used to denote Boolean values.Examples:
+Examples:
1> 2 =< 3. true @@ -329,76 +347,80 @@ true|
\b | -backspace | +Backspace | |
\d | -delete | +Delete | |
\e | -escape | +Escape | |
\f | -form feed | +Form feed | |
\n | -newline | +Newline | |
\r | -carriage return | +Carriage return | |
\s | -space | +Space | |
\t | -tab | +Tab | |
\v | -vertical tab | +Vertical tab | |
\XYZ, \YZ, \Z | -character with octal representation XYZ, YZ or Z | +Character with octal + representation XYZ, YZ or Z | |
\xXY | -character with hexadecimal representation XY | +Character with hexadecimal + representation XY | |
\x{X...} | -character with hexadecimal representation; X... is one or more hexadecimal characters | +Character with hexadecimal + representation; X... is one or more hexadecimal characters | |
\^a...\^z | -
\^A...\^Zcontrol A to control Z | +Control A to control Z | |
\' | -single quote | +Single quote | |
\" | -double quote | +Double quote | -
\\ | -backslash | +Backslash | Recognized Escape Sequences. +Recognized Escape Sequences Type Conversions -There are a number of BIFs for type conversions. Examples:
+There are a number of BIFs for type conversions.
+Examples:
1> atom_to_list(hello). "hello" diff --git a/system/doc/reference_manual/distributed.xml b/system/doc/reference_manual/distributed.xml index 88f98bc106..fb83e356f9 100644 --- a/system/doc/reference_manual/distributed.xml +++ b/system/doc/reference_manual/distributed.xml @@ -4,7 +4,7 @@- 2003 2013 +2003 2015 Ericsson AB. All Rights Reserved. @@ -36,22 +36,24 @@ runtime system is called a node. Message passing between processes at different nodes, as well as links and monitors, are transparent when pids are used. Registered names, however, are - local to each node. This means the node must be specified as well - when sending messages etc. using registered names. + local to each node. This means that the node must be specified as well + when sending messages, and so on, using registered names. The distribution mechanism is implemented using TCP/IP sockets. - How to implement an alternative carrier is described in ERTS User's Guide.
+ How to implement an alternative carrier is described in the +ERTS User's Guide .Nodes -A node is an executing Erlang runtime system which has - been given a name, using the command line flag
-name +A node is an executing Erlang runtime system that has + been given a name, using the command-line flag
--name (long names) or-sname (short names).The format of the node name is an atom
name@host where -name is the name given by the user andhost is +The format of the node name is an atom
+ the name of the node. +name@host . +name is the name given by the user.host is the full host name if long names are used, or the first part of the host name if short names are used.node() returns - the name of the node. Example:Example:
% erl -name dilbert (dilbert@uab.ericsson.se)1> node(). @@ -69,16 +71,16 @@ dilbert@uabNode Connections The nodes in a distributed Erlang system are loosely connected. - The first time the name of another node is used, for example if + The first time the name of another node is used, for example, if
+ a connection attempt to that node is made.spawn(Node,M,F,A) ornet_adm:ping(Node) is called, - a connection attempt to that node will be made.Connections are by default transitive. If a node A connects to - node B, and node B has a connection to node C, then node A will - also try to connect to node C. This feature can be turned off by - using the command line flag
+ node B, and node B has a connection to node C, then node A + also tries to connect to node C. This feature can be turned off by + using the command-line flag-connect_all false , see -erl(1) .-connect_all false , see the +erl(1) manual page in ERTS.If a node goes down, all connections to that node are removed. - Calling
erlang:disconnect_node(Node) will force disconnection + Callingerlang:disconnect_node(Node) forces disconnection of a node.The list of (visible) nodes currently connected to is returned by
@@ -89,23 +91,24 @@ dilbert@uabnodes() .The Erlang Port Mapper Daemon epmd is automatically started at every host where an Erlang node is started. It is responsible for mapping the symbolic node names to machine - addresses. See
+ addresses. See the +epmd(1) .epmd(1) manual page in ERTS.@@ -114,9 +117,11 @@ dilbert@uab Hidden Nodes In a distributed Erlang system, it is sometimes useful to connect to a node without also connecting to all other nodes. - An example could be some kind of O&M functionality used to - inspect the status of a system without disturbing it. For this - purpose, a hidden node may be used.
-A hidden node is a node started with the command line flag + An example is some kind of O&M functionality used to + inspect the status of a system, without disturbing it. For this + purpose, a hidden node can be used.
+A hidden node is a node started with the command-line flag
-hidden . Connections between hidden nodes and other nodes are not transitive, they must be set up explicitly. Also, hidden nodes does not show up in the list of nodes returned bynodes() . Instead,nodes(hidden) ornodes(connected) must be used. This means, for example, - that the hidden node will not be added to the set of nodes that + that the hidden node is not added to the set of nodes thatglobal is keeping track of.This feature was added in Erlang 5.0/OTP R7.
A C node is a C program written to act as a hidden node in a distributed Erlang system. The library Erl_Interface - contains functions for this purpose. Refer to the documentation - for Erl_Interface and Interoperability Tutorial for more - information about C nodes.
+ contains functions for this purpose. For more information about + C nodes, see theWhen a nodes tries to connect to another node, the magic cookies +
When a node tries to connect to another node, the magic cookies are compared. If they do not match, the connected node rejects the connection.
At start-up, a node has a random atom assigned as its magic
@@ -141,8 +146,8 @@ dilbert@uab
the local node assume that all other nodes have the same cookie
Thus, groups of users with identical cookie files get Erlang - nodes which can communicate freely and without interference from - the magic cookie system. Users who want run nodes on separate + nodes that can communicate freely and without interference from + the magic cookie system. Users who want to run nodes on separate file systems must make certain that their cookie files are identical on the different file systems.
For a node
The default when a connection is established between two nodes,
is to immediately connect all other visible nodes as well. This
way, there is always a fully connected network. If there are
- nodes with different cookies, this method might be inappropriate
- and the command line flag
The magic cookie of the local node is retrieved by calling
Some useful BIFs for distributed programming, see
-
Some useful BIFs for distributed programming
+ (for more information, see the
Examples of command line flags used for distributed programming,
- see
Examples of command-line flags used for distributed programming
+ (for more information, see the
Examples of modules useful for distributed programming:
-In Kernel:
+In the Kernel application:
In STDLIB:
+In the STDLIB application:
An exception consists of its class, an exit reason
- (the
The stack trace can be retrieved using
-
An exception of class
It is possible to prevent run-time errors and other
exceptions from causing
the process to terminate by using
Processes can monitor other processes and detect process
terminations, see
- the
When a run-time error occurs,
- that is an exception of class
When a run-time error occurs,
+ that is an exception of class
In this chapter, all valid Erlang expressions are listed. +
In this section, all valid Erlang expressions are listed.
When writing Erlang programs, it is also allowed to use macro-
and record expressions. However, these expressions are expanded
during compilation and are in that sense not true Erlang
expressions. Macro- and record expressions are covered in
- separate chapters:
Many of the operators can only be applied to arguments of a
certain type. For example, arithmetic operators can only be
- applied to numbers. An argument of the wrong type will cause
- a
The simplest form of expression is a term, that is an integer, - float, atom, string, list, map or tuple. + float, atom, string, list, map, or tuple. The return value is the term itself.
A variable is an expression. If a variable is bound to a value, the return value is this value. Unbound variables are only allowed in patterns.
-Variables start with an uppercase letter or underscore (_) - and may contain alphanumeric characters, underscore and @. - Examples:
+Variables start with an uppercase letter or underscore (_).
+ Variables can contain alphanumeric characters, underscore and
Examples:
X Name1 @@ -77,18 +82,20 @@ _ _Height
Variables are bound to values using
The anonymous variable is denoted by underscore (_) and can be used when a variable is required but its value can be - ignored. Example:
+ ignored. +Example:
[H|_] = [1,2,3]-
Variables starting with underscore (_), for example +
Variables starting with underscore (_), for example,
Example:
+The following code:
member(_, []) -> [].@@ -96,36 +103,37 @@ member(_, []) ->
member(Elem, []) -> [].-
This will however cause a warning for an unused variable +
This causes a warning for an unused variable,
member(_Elem, []) -> [].-
Note that since variables starting with an underscore are - not anonymous, this will match:
+Notice that since variables starting with an underscore are + not anonymous, this matches:
{_,_} = {1,2}-
But this will fail:
+But this fails:
{_N,_N} = {1,2}
The scope for a variable is its function clause.
Variables bound in a branch of an
For the
A pattern has the same structure as a term but may contain - unbound variables. Example:
+A pattern has the same structure as a term but can contain + unbound variables.
+Example:
Name1 [H|T] @@ -136,13 +144,13 @@ Name1Match Operator = in Patterns If
+ the following is also a valid pattern:Pattern1 andPattern2 are valid patterns, - then the following is also a valid pattern:Pattern1 = Pattern2When matched against a term, both
+Pattern1 and -Pattern2 will be matched against the term. The idea - behind this feature is to avoid reconstruction of terms. - Example:Pattern2 are matched against the term. The idea + behind this feature is to avoid reconstruction of terms. +Example:
f({connect,From,To,Number,Options}, To) -> Signal = {connect,From,To,Number,Options}, @@ -163,16 +171,20 @@ f(Signal, To) ->f("prefix" ++ Str) -> ...This is syntactic sugar for the equivalent, but harder to - read
+ read:f([$p,$r,$e,$f,$i,$x | Str]) -> ...Expressions in Patterns -An arithmetic expression can be used within a pattern, if - it uses only numeric or bitwise operators, and if its value - can be evaluated to a constant at compile-time. Example:
+An arithmetic expression can be used within a pattern if + it meets both of the following two conditions:
++
+- It uses only numeric or bitwise operators.
+- Its value can be evaluated to a constant when complied.
+Example:
case {Value, Result} of {?THRESHOLD+1, ok} -> ...@@ -182,21 +194,21 @@ case {Value, Result} ofMatch +The following matches
Expr1 , a pattern, against +Expr2 :Expr1 = Expr2-Matches
Expr1 , a pattern, againstExpr2 . - If the matching succeeds, any unbound variable in the pattern +If the matching succeeds, any unbound variable in the pattern becomes bound and the value of
-Expr2 is returned.If the matching fails, a
-badmatch run-time error will - occur.Examples:
+If the matching fails, a
+badmatch run-time error occurs.Examples:
1> {A, B} = {answer, 42}. {answer,42} 2> A. answer 3> {C, D} = [1, 2]. -** exception error: no match of right hand side value [1,2]+** exception error: no match of right-hand side value [1,2]
Example:
lists:keysearch(Name, 1, List)
In the second form of function calls,
If
If
Examples:
handle(Msg, State)
spawn(m, init, [])
- Examples where ExprF is a fun:
+Examples where
Fun1 = fun(X) -> X+1 end
Fun1(3)
@@ -239,16 +252,15 @@ Fun1(3)
fun lists:append/2([1,2], [3,4])
=> [1,2,3,4]
- Note that when calling a local function, there is a difference
- between using the implicitly or fully qualified function name, as
- the latter always refers to the latest version of the module. See
-
See also the chapter about
-
Notice that when calling a local function, there is a difference
+ between using the implicitly or fully qualified function name.
+ The latter always refers to the latest version of the module.
+ See
If a local function has the same name as an auto-imported BIF,
the semantics is that implicitly qualified function calls are
directed to the locally defined function, not to the BIF. To avoid
@@ -260,9 +272,9 @@ fun lists:append/2([1,2], [3,4])
Before OTP R14A (ERTS version 5.8), an implicitly
qualified function call to a function having the same name as an
auto-imported BIF always resulted in the BIF being called. In
- newer versions of the compiler the local function is instead
- called. The change is there to avoid that future additions to the
- set of auto-imported BIFs does not silently change the behavior
+ newer versions of the compiler, the local function is called instead.
+ This is to avoid that future additions to the
+ set of auto-imported BIFs do not silently change the behavior
of old code. However, to avoid that old (pre R14) code changed its
@@ -272,8 +284,8 @@ fun lists:append/2([1,2], [3,4])
5.8) and have an implicitly qualified call to that function in
your code, you either need to explicitly remove the auto-import
using a compiler directive, or replace the call with a fully
- qualified function call, otherwise you will get a compilation
- error. See example below:
-export([length/1,f/1]).
@@ -290,9 +302,10 @@ f(X) when erlang:length(X) > 3 -> %% Calls erlang:length/1,
long.
The same logic applies to explicitly imported functions from - other modules as to locally defined functions. To both import a + other modules, as to locally defined functions. + It is not allowed to both import a function from another module and have the function declared in the - module at the same time is not allowed.
+ module at the same time:
-export([f/1]).
@@ -310,10 +323,10 @@ f(X) ->
length(X). %% mod:length/1 is called
- For auto-imported BIFs added to Erlang in release R14A and thereafter, +
For auto-imported BIFs added in Erlang/OTP R14A and thereafter,
overriding the name with a local function or explicit import is always
allowed. However, if the
The branches of an
The return value of
If no guard sequence is true, an
If no guard sequence is evaluated as true,
+ an
Example:
+Example:
is_greater_than(X, Y) -> if @@ -367,8 +381,8 @@ end
The return value of
If there is no matching pattern with a true guard sequence,
- a
Example:
+ aExample:
is_valid_signal(Signal) -> case Signal of @@ -389,15 +403,15 @@ Expr1 ! Expr2
Sends the value of
The return value of
Example:
+Example:
wait_for_onhook() -> receive @@ -438,7 +452,7 @@ wait_for_onhook() -> B ! {busy, self()}, wait_for_onhook() end.-
It is possible to augment the
The
receive @@ -451,14 +465,14 @@ after ExprT -> BodyT end-
Example:
+ milliseconds, thenExample:
wait_for_onhook() -> receive @@ -481,10 +495,10 @@ after ExprT -> BodyT end-
This construction will not consume any messages, only suspend
- execution in the process for
This construction does not consume any messages, only suspends
+ execution in the process for
Example:
+Example:
timer() -> spawn(m, timer, [self()]). @@ -498,12 +512,12 @@ timer(Pid) ->There are two special cases for the timeout value
ExprT :- infinity - The process should wait indefinitely for a matching message - -- this is the same as not using a timeout. Can be - useful for timeout values that are calculated at run-time.
+- The process is to wait indefinitely for a matching message; + this is the same as not using a timeout. This can be + useful for timeout values that are calculated at runtime.
0 - If there is no matching message in the mailbox, the timeout - will occur immediately.
+ occurs immediately.
The arguments may be of different data types. The following +
The arguments can be of different data types. The following order is defined:
number < atom < reference < fun < port < pid < tuple < list < bit string@@ -558,17 +572,18 @@ number < atom < reference < fun < port < pid < tuple < list size, two tuples with the same size are compared element by element.
When comparing an integer to a float, the term with the lesser
- precision will be converted into the other term's type, unless the
- operator is one of =:= or =/=. A float is more precise than
+ precision is converted into the type of the other term, unless the
+ operator is one of
Returns the Boolean value of the expression,
Examples:
+Term comparison operators return the Boolean value of the
+ expression,
Examples:
1> 1==1.0. true @@ -585,19 +600,19 @@ falseExpr1 op Expr2
Examples:
+Examples:
1> +1. 1 @@ -697,28 +712,28 @@ Expr1 op Expr2Expr1 op Expr2
Examples:
+Examples:
1> not true. false @@ -737,28 +752,37 @@ trueExpr1 orelse Expr2 Expr1 andalso Expr2-Expressions where
Expr2 is evaluated only if - necessary. That is,Expr2 is evaluated only ifExpr1 - evaluates tofalse in anorelse expression, or only - ifExpr1 evaluates totrue in anandalso - expression. Returns either the value ofExpr1 (that is, ++
Expr2 is evaluated only if + necessary. That is,Expr2 is evaluated only if:+
+- +
+
Expr1 evaluates tofalse in an +orelse expression.or
++
+- +
+
Expr1 evaluates totrue in an +andalso expression.Returns either the value of
+ (ifExpr1 (that is,true orfalse ) or the value ofExpr2 - (ifExpr2 was evaluated).Expr2 is evaluated). -Example 1:
+Example 1:
case A >= -1.0 andalso math:sqrt(A+1) > B of-This will work even if
A is less than-1.0 , +This works even if
-A is less than-1.0 , since in that case,math:sqrt/1 is never evaluated.Example 2:
+Example 2:
OnlyOne = is_atom(L) orelse (is_list(L) andalso length(L) == 1),-From R13A,
Expr2 is no longer required to evaluate to a - boolean value. As a consequence,andalso andorelse +From Erlang/OTP R13A,
+ tail-recursive in Erlang/OTP R13A and later:Expr2 is no longer required to evaluate to a + Boolean value. As a consequence,andalso andorelse are now tail-recursive. For instance, the following function is - tail-recursive in R13A and later:all(Pred, [Hd|Tail]) -> @@ -774,11 +798,11 @@ Expr1 ++ Expr2 Expr1 -- Expr2The list concatenation operator
-++ appends its second argument to its first and returns the resulting list.The list subtraction operator
-- produces a list which - is a copy of the first argument, subjected to the following - procedure: for each element in the second argument, the first +The list subtraction operator
--- produces a list that + is a copy of the first argument. The procedure is a follows: + for each element in the second argument, the first occurrence of this element (if any) is removed.Example:
+Example:
1> [1,2,3]++[4,5]. [1,2,3,4,5] @@ -786,8 +810,8 @@ Expr1 -- Expr2[3,1,2]
The complexity of
#{ K => V }
- New maps may include multiple associations at construction by listing every + New maps can include multiple associations at construction by listing every association:
#{ K1 => V1, .., Kn => Vn }
@@ -816,11 +840,11 @@ Expr1 -- Expr2
Keys and values are separated by the
- Examples: + Examples:
M0 = #{}, % empty map
@@ -829,14 +853,14 @@ M2 = #{1 => 2, b => b}, % multiple associations with literals
M3 = #{k => {A,B}}, % single association with variables
M4 = #{{"w", 1} => f()}. % compound key associated with an evaluated expression
- where,
- If two matching keys are declared, the latter key will take precedence. + If two matching keys are declared, the latter key takes precedence.
- Example: + Example:
@@ -846,54 +870,57 @@ M4 = #{{"w", 1} => f()}. % compound key associated with an evaluated expression #{1 => b, 1.0 => a}
- The order in which the expressions constructing the keys and their - associated values are evaluated is not defined. The syntactic order of + The order in which the expressions constructing the keys (and their + associated values) are evaluated is not defined. The syntactic order of the key-value pairs in the construction is of no relevance, except in - the above mentioned case of two matching keys. + the recently mentioned case of two matching keys.
- Updating a map has similar syntax as constructing it. + Updating a map has a similar syntax as constructing it.
- An expression defining the map to be updated is put in front of the expression - defining the keys to be updated and their respective values. + An expression defining the map to be updated, is put in front of the expression + defining the keys to be updated and their respective values:
M#{ K => V }
- where
If key
If key
- If
- To only update an existing value, the following syntax is used, + To only update an existing value, the following syntax is used:
M#{ K := V }
- where
- If key
- If
- Examples: + Examples:
M0 = #{},
@@ -902,10 +929,10 @@ M2 = M1#{a => 1, b => 2},
M3 = M2#{"function" => fun() -> f() end},
M4 = M3#{a := 2, b := 3}. % 'a' and 'b' was added in `M1` and `M2`.
- where
- More Examples: + More Examples:
1> M = #{1 => a}. @@ -921,83 +948,84 @@ M4 = M3#{a := 2, b := 3}. % 'a' and 'b' was added in `M1` and `M2`. As in construction, the order in which the key and value expressions are evaluated is not defined. The syntactic order of the key-value pairs in the update is of no - relevance, except in the case where two keys match, in which - case the latter value is used. + relevance, except in the case where two keys match. + In that case, the latter value is used.
- Matching of key-value associations from maps is done in the following way: + Matching of key-value associations from maps is done as follows:
#{ K := V } = M
- where
- If the variable
Example:
-
+ Example:
+
1> M = #{"tuple" => {1,2}}.
#{"tuple" => {1,2}}
2> #{"tuple" := {1,B}} = M.
#{"tuple" => {1,2}}
3> B.
-2.
+2.
- This will bind variable
- Similarly, multiple values from the map may be matched: + Similarly, multiple values from the map can be matched:
#{ K1 := V1, .., Kn := Vn } = M
- where keys
- If the matching conditions are not met, the match will fail, either with + If the matching conditions are not met, the match fails, either with:
A
This is if it is used in the context of the matching operator + as in the example.
Or resulting in the next clause being tested in function heads and + case expressions.
Matching in maps only allows for
The order in which keys are declared in matching has no relevance.
- Duplicate keys are allowed in matching and will match each pattern associated - to the keys. + Duplicate keys are allowed in matching and match each pattern associated + to the keys:
#{ K := V1, K := V2 } = M
- Matching an expression against an empty map literal will match its type but - no variables will be bound: + Matching an expression against an empty map literal, matches its type but + no variables are bound:
#{} = Expr
- This expression will match if the expression
- Matching of literals as keys are allowed in function heads. + Matching of literals as keys are allowed in function heads:
%% only start if not_started
@@ -1014,17 +1042,19 @@ handle_call(change, From, #{ state := start } = S) ->
Maps in Guards
- Maps are allowed in guards as long as all sub-expressions are valid guard expressions.
+ Maps are allowed in guards as long as all subexpressions are valid guard expressions.
- Two guard BIFs handles maps:
+ Two guard BIFs handle maps:
-
is_map/1
+ in the erlang module
-
map_size/1
+ in the erlang module
@@ -1044,29 +1074,34 @@ Ei = Value |
Value/TypeSpecifierList |
Value:Size/TypeSpecifierList
Used in a bit string construction, Value is an expression
- which should evaluate to an integer, float or bit string. If the
- expression is something else than a single literal or variable, it
- should be enclosed in parenthesis.
+ that is to evaluate to an integer, float, or bit string. If the
+ expression is not a single literal or variable, it
+ is to be enclosed in parenthesis.
Used in a bit string matching, Value must be a variable,
- or an integer, float or string.
+ or an integer, float, or string.
- Note that, for example, using a string literal as in
+
Notice that, for example, using a string literal as in
>]]> is syntactic sugar for
>]]> .
Used in a bit string construction, Size is an expression
- which should evaluate to an integer.
+ that is to evaluate to an integer.
- Used in a bit string matching, Size must be an integer or a
+
Used in a bit string matching, Size must be an integer, or a
variable bound to an integer.
The value of Size specifies the size of the segment in
units (see below). The default value depends on the type (see
- below). For integer it is 8, for
- float it is 64, for binary and bitstring it is
- the whole binary or bit string. In matching, this default value is only
- valid for the very last element. All other bit string or binary
+ below):
+
+ - For
integer it is 8.
+ - For
float it is 64.
+ - For
binary and bitstring it is
+ the whole binary or bit string.
+
+ In matching, this default value is only
+ valid for the last element. All other bit string or binary
elements in the matching must have a size specification.
For the utf8 , utf16 , and utf32 types,
@@ -1090,7 +1125,7 @@ Ei = Value |
The default is unsigned .
Endianness = big | little | native
- - Native-endian means that the endianness will be resolved at load
+
- Native-endian means that the endianness is resolved at load
time to be either big-endian or little-endian, depending on
what is native for the CPU that the Erlang machine is run on.
Endianness only matters when the Type is either
integer ,
@@ -1099,7 +1134,7 @@ Ei = Value |
Unit = unit:IntegerLiteral
- The allowed range is 1..256. Defaults to 1 for
integer ,
- float and bitstring , and to 8 for binary .
+ float , and bitstring , and to 8 for binary .
No unit specifier must be given for the types
utf8 , utf16 , and utf32 .
@@ -1110,8 +1145,8 @@ Ei = Value |
When constructing binaries, if the size N of an integer
segment is too small to contain the given integer, the most significant
- bits of the integer will be silently discarded and only the N least
- significant bits will be put into the binary.
+ bits of the integer are silently discarded and only the N least
+ significant bits are put into the binary.
The types utf8 , utf16 , and utf32 specifies
encoding/decoding of the Unicode Transformation Formats UTF-8, UTF-16,
@@ -1120,39 +1155,39 @@ Ei = Value |
When constructing a segment of a utf type, Value
must be an integer in the range 0..16#D7FF or
16#E000....16#10FFFF. Construction
- will fail with a badarg exception if Value is
+ fails with a badarg exception if Value is
outside the allowed ranges. The size of the resulting binary
- segment depends on the type and/or Value . For utf8 ,
- Value will be encoded in 1 through 4 bytes. For
- utf16 , Value will be encoded in 2 or 4
- bytes. Finally, for utf32 , Value will always be
- encoded in 4 bytes.
+ segment depends on the type or Value , or both:
+
+ - For
utf8 , Value is encoded in 1-4 bytes.
+ - For
utf16 , Value is encoded in 2 or 4 bytes.
+ - For
utf32 , Value is always be encoded in 4 bytes.
+
- When constructing, a literal string may be given followed
+
When constructing, a literal string can be given followed
by one of the UTF types, for example: >]]>
- which is syntatic sugar for
+ which is syntactic sugar for
>]]> .
- A successful match of a segment of a utf type results
+
A successful match of a segment of a utf type, results
in an integer in the range 0..16#D7FF or 16#E000..16#10FFFF.
- The match will fail if returned value
- would fall outside those ranges.
+ The match fails if the returned value falls outside those ranges.
- A segment of type utf8 will match 1 to 4 bytes in the binary,
+
A segment of type utf8 matches 1-4 bytes in the binary,
if the binary at the match position contains a valid UTF-8 sequence.
(See RFC-3629 or the Unicode standard.)
- A segment of type utf16 may match 2 or 4 bytes in the binary.
- The match will fail if the binary at the match position does not contain
+
A segment of type utf16 can match 2 or 4 bytes in the binary.
+ The match fails if the binary at the match position does not contain
a legal UTF-16 encoding of a Unicode code point. (See RFC-2781 or
the Unicode standard.)
- A segment of type utf32 may match 4 bytes in the binary in the
- same way as an integer segment matching 32 bits.
- The match will fail if the resulting integer is outside the legal ranges
+
A segment of type utf32 can match 4 bytes in the binary in the
+ same way as an integer segment matches 32 bits.
+ The match fails if the resulting integer is outside the legal ranges
mentioned above.
- Examples:
+ Examples:
1> Bin1 = <<1,17,42>>.
<<1,17,42>>
@@ -1181,11 +1216,13 @@ Ei = Value |
13> <<1024/utf8>>.
<<208,128>>
- Note that bit string patterns cannot be nested.
- Note also that ">]]> " is interpreted as
+
Notice that bit string patterns cannot be nested.
+ Notice also that ">]]> " is interpreted as
">]]> " which is a syntax error. The correct way is
to write a space after '=': ">]]> .
- More examples can be found in Programming Examples.
+ More examples are provided in
+
+ Programming Examples .
A fun expression begins with the keyword
Variables in a fun head shadow the function name and both shadow - variables in the function clause surrounding the fun expression, and - variables bound in a fun body are local to the fun body.
+ variables in the function clause surrounding the fun expression. + Variables bound in a fun body are local to the fun body.The return value of the expression is the resulting fun.
-Examples:
+Examples:
1> Fun1 = fun (X) -> X+1 end. #Fun<erl_eval.6.39074546> @@ -1232,15 +1269,17 @@ fun Module:Name/Aritysyntactic sugar for:
fun (Arg1,...,ArgN) -> Name(Arg1,...,ArgN) end-
In
In
More examples can be found in Programming Examples.
+More examples are provided in
+
Returns the value of
For exceptions of class
For exceptions of class
For exceptions of class
Examples:
- +Examples:
1> catch 1+2. 3 2> catch 1+a. {'EXIT',{badarith,[...]}}-
Note that
Notice that
@@ -1275,13 +1317,14 @@ catch Expr 4> A = (catch 1+2). 3
The BIF
Example:
5> catch throw(hello). hello
If
This is an enhancement of
Note that although the keyword
Notice that although the keyword
Returns the value of
It returns the value of
If an exception occurs during evaluation of
If an exception occurs during evaluation of
The
An exception occurring during the evaluation of
The
Even if an exception occurs during evaluation of
If an exception occurs during evaluation of
The
The
try Exprs of
@@ -1398,9 +1444,9 @@ after
end
try Exprs after AfterBody end
- Example of using
Next is an example of using
termize_file(Name) ->
@@ -1411,7 +1457,7 @@ termize_file(Name) ->
after
file:close(F)
end.
- Example: Using
Next is an example of using
try Expr
catch
@@ -1427,7 +1473,7 @@ end
(Expr)
Parenthesized expressions are useful to override
1> 1 + 2 * 3. 7 @@ -1451,7 +1497,7 @@ end
List comprehensions are a feature of many modern functional +
List comprehensions is a feature of many modern functional programming languages. Subject to certain rules, they provide a succinct notation for generating elements in a list.
List comprehensions are analogous to set comprehensions in @@ -1461,32 +1507,34 @@ end
List comprehensions are written with the following syntax:
[Expr || Qualifier1,...,QualifierN]-
Here,
The variables in the generator patterns shadow variables in the function - clause surrounding the list comprehensions.
A list comprehension +
The variables in the generator patterns, shadow variables in the function + clause, surrounding the list comprehensions.
A list comprehension
returns a list, where the elements are the result of evaluating
Example:
+ elements, for which all filters are true. +Example:
1> [X*2 || X <- [1,2,3]]. [2,4,6]-
More examples can be found in Programming Examples.
- +More examples are provoded in
+
<< BitString || Qualifier1,...,QualifierN >>-
Here,
The variables in the generator patterns shadow variables in - the function clause surrounding the bit string comprehensions.
+The variables in the generator patterns, shadow variables in + the function clause, surrounding the bit string comprehensions.
A bit string comprehension returns a bit string, which is
created by concatenating the results of evaluating
Example:
+Example:
-1> << << (X*2) >> || +1> << << (X*2) >> || <<X>> <= << 1,2,3 >> >>. <<2,4,6>>-
More examples can be found in Programming Examples.
+More examples are provided in
+
A guard sequence is a sequence of guards, separated
by semicolon (;). The guard sequence is true if at least one of
- the guards is true. (The remaining guards, if any, will not be
- evaluated.)
-
A guard is a sequence of guard expressions, separated
by comma (,). The guard is true if all guard expressions
- evaluate to
-
The set of valid guard expressions (sometimes called guard tests) is a subset of the set of valid Erlang expressions. The reason for restricting the set of valid expressions is that evaluation of a guard expression must be guaranteed to be free - of side effects. Valid guard expressions are:
+ of side effects. Valid guard expressions are the following:Note that most type test BIFs have older equivalents, without +
Notice that most type test BIFs have older equivalents, without
the
If an arithmetic expression, a boolean expression, a +
If an arithmetic expression, a Boolean expression, a short-circuit expression, or a call to a guard BIF fails (because of invalid arguments), the entire guard fails. If the guard was part of a guard sequence, the next guard in the sequence (that is, - the guard following the next semicolon) will be evaluated.
+ the guard following the next semicolon) is evaluated.When evaluating an expression, the operator with the highest priority is evaluated first. Operators with the same priority - are evaluated according to their associativity. Example: - The left associative arithmetic operators are evaluated left to + are evaluated according to their associativity.
+Example:
+The left associative arithmetic operators are evaluated left to right:
6 + 5 * 4 - 3 / 2 evaluates to diff --git a/system/doc/reference_manual/functions.xml b/system/doc/reference_manual/functions.xml index 9498ef1402..8cf4da1b8b 100644 --- a/system/doc/reference_manual/functions.xml +++ b/system/doc/reference_manual/functions.xml @@ -4,7 +4,7 @@- 2003 2013 +2003 2015 Ericsson AB. All Rights Reserved. @@ -38,7 +38,7 @@ clause body, separated by -> .A clause head consists of the function name, an argument list, and an optional guard sequence - beginning with the keyword
+ beginning with the keywordwhen .when :Name(Pattern11,...,Pattern1N) [when GuardSeq1] -> Body1; @@ -48,9 +48,9 @@ Name(PatternK1,...,PatternKN) [when GuardSeqK] ->The function name is an atom. Each argument is a pattern.
The number of arguments
+ different functions.N is the arity of the function. A function is uniquely defined by the module name, - function name and arity. That is, two functions with the same + function name, and arity. That is, two functions with the same name and in the same module, but with different arities are two - completely different functions.A function named
f in the modulem and with arityN is often denoted asm:f/N .A clause body consists of a sequence of expressions @@ -60,8 +60,8 @@ Expr1, ..., ExprN
Valid Erlang expressions and guard sequences are described in -
-Erlang Expressions .Example:
+Expressions . +Example:
fact(N) when N>0 -> % first clause head N * fact(N-1); % first clause body @@ -75,23 +75,23 @@ fact(0) -> % second clause headFunction Evaluation When a function
m:f/N is called, first the code for the function is located. If the function cannot be found, an -undef run-time error will occur. Note that the function +undef runtime error occurs. Notice that the function must be exported to be visible outside the module it is defined in.If the function is found, the function clauses are scanned - sequentially until a clause is found that fulfills the following - two conditions:
+ sequentially until a clause is found that fulfills both of + the following two conditions:-
- the patterns in the clause head can be successfully - matched against the given arguments, and
-- the guard sequence, if any, is true.
+- The patterns in the clause head can be successfully + matched against the given arguments.
+- The guard sequence, if any, is true.
If such a clause cannot be found, a
+ runtime error occurs.function_clause - run-time error will occur.If such a clause is found, the corresponding clause body is evaluated. That is, the expressions in the body are evaluated sequentially and the value of the last expression is returned.
-Example: Consider the function
+fact :Consider the function
fact :-module(m). -export([fact/1]). @@ -100,17 +100,17 @@ fact(N) when N>0 -> N * fact(N-1); fact(0) -> 1.-Assume we want to calculate factorial for 1:
+Assume that you want to calculate the factorial for 1:
1> m:fact(1).Evaluation starts at the first clause. The pattern
N is - matched against the argument 1. The matching succeeds and - the guard (N>0 ) is true, thusN is bound to 1 and + matched against argument 1. The matching succeeds and + the guard (N>0 ) is true, thusN is bound to 1, and the corresponding body is evaluated:N * fact(N-1) => (N is bound to 1) 1 * fact(0)-Now
fact(0) is called and the function clauses are +Now,
fact(0) is called, and the function clauses are scanned sequentially again. First, the patternN is matched against 0. The matching succeeds, but the guard (N>0 ) is false. Second, the pattern 0 is matched against @@ -121,48 +121,51 @@ fact(0) -> 1Evaluation has succeed and
m:fact(1) returns 1.If
+ argument, no clause head matches. Am:fact/1 is called with a negative number as - argument, no clause head will match. Afunction_clause - run-time error will occur.function_clause + runtime error occurs.
If the last expression of a function body is a function call, - a tail recursive call is done so that no system - resources for example call stack are consumed. This means - that an infinite loop can be done if it uses tail recursive + a tail recursive call is done. + This is to ensure that no system + resources, for example, call stack, are consumed. This means + that an infinite loop can be done if it uses tail-recursive calls.
-Example:
+Example:
loop(N) -> io:format("~w~n", [N]), loop(N+1).-
As a counter-example see the factorial example above - that is not tail recursive since a multiplication is done +
The earlier factorial example can act as a counter-example.
+ It is not tail-recursive, since a multiplication is done
on the result of the recursive call to
Built-in functions, BIFs, are implemented in C code in
- the runtime system and do things that are difficult or impossible
- to implement in Erlang. Most of the built-in functions belong
- to the module
BIFs are implemented in C code in
+ the runtime system. BIFs do things that are difficult or impossible
+ to implement in Erlang. Most of the BIFs belong
+ to the module
The most commonly used BIFs belonging to
The most commonly used BIFs belonging to
Examples:
1> tuple_size({a,b,c}). 3 2> atom_to_list('Erlang'). "Erlang"-
Note that normally it is the set of auto-imported built-in - functions that is referred to when talking about 'BIFs'.
+Notice that it is normally the set of auto-imported BIFs + that are referred to when talking about 'BIFs'.
This section is the Erlang reference manual. It describes the + Erlang programming language.
This reference manual describes the Erlang programming - language. The focus is on the language itself, not - the implementation. The language constructs are described in - text and with examples rather than formally specified, with - the intention to make the manual more readable. - The manual is not intended as a tutorial.
-Information about this implementation of Erlang can be found, for - example, in System Principles (starting and stopping, - boot scripts, code loading, error logging, creating target - systems), Efficiency Guide (memory consumption, system - limits) and ERTS User's Guide (crash dumps, drivers).
+The focus of the Erlang reference manual is on the language itself, + not the implementation of it. The language constructs are described in + text and with examples rather than formally specified. This is + to make the manual more readable. + The Erlang reference manual is not intended as a tutorial.
+Information about implementation of Erlang can, for example, be found, + in the following:
+Starting and stopping, boot scripts, code loading,
+
Memory consumption, system limits
+ERTS User's Guide
+In the document, the following terminology is used:
+In this section, the following terminology is used:
If a feature has been added recently, in Erlang 5.0/OTP R7 or later, this is mentioned in the text.
@@ -68,15 +86,16 @@For a complete list of BIFs, their arguments and return values,
- refer to
The following are reserved words in Erlang:
-after and andalso band begin bnot bor bsl bsr bxor case catch +
A file can be included in the following way:
+A file can be included as follows:
-include(File). -include_lib(File).-
Include files are typically used for record and macro
definitions that are shared by several modules. It is
- recommended that the file name extension
If the filename
Examples:
+ included. Otherwise, the specified file is searched for + in the following directories, and in this order: +For details, see the
+
Examples:
-include("my_records.hrl"). -include("incdir/my_records.hrl"). -include("/home/user/proj/my_records.hrl"). -include("$PROJ_ROOT/my_records.hrl").-
Example:
-include_lib("kernel/include/file.hrl").
The code server uses A macro is defined the following way: A macro is defined as follows:
-define(Const, Replacement).
-define(Func(Var1,...,VarN), Replacement).
@@ -83,33 +91,34 @@
come before any usage of the macro.
If a macro is used in several modules, it is recommended that the macro definition is placed in an include file.
-A macro is used the following way:
+A macro is used as follows:
?Const
?Func(Arg1,...,ArgN)
Macros are expanded during compilation. A simple macro
-
Example:
-define(TIMEOUT, 200).
...
call(Request) ->
server:call(refserver, Request, ?TIMEOUT).
- This will be expanded to:
+This is expanded to:
call(Request) ->
server:call(refserver, Request, 200).
- A macro
A macro
Example:
-define(MACRO1(X, Y), {a, X, b, Y}).
...
bar(X) ->
?MACRO1(a, b),
?MACRO1(X, 123)
- This will be expanded to:
+This is expanded to:
bar(X) ->
{a,a,b,b},
@@ -154,7 +163,7 @@ bar(X) ->
-define(F0(), c).
-define(F1(A), A).
-define(C, m:f).
- the following will not work:
+the following does not work:
f0() ->
?F0. % No, an empty list of arguments expected.
@@ -165,7 +174,7 @@ f1(A) ->
f() ->
?C().
- will expand to
+ is expanded to
f() ->
m:f().
@@ -185,7 +194,7 @@ f() ->
defined.
-else.
- Only allowed after an
ifdef or ifndef
- directive. If that condition was false, the lines following
+ directive. If that condition is false, the lines following
else are evaluated instead.
-endif.
- Specifies the end of an
ifdef or ifndef
@@ -194,7 +203,7 @@ f() ->
The macro directives cannot be used inside functions.
- Example:
+ Example:
-module(m).
...
@@ -206,7 +215,7 @@ f() ->
-endif.
...
- When trace output is desired, debug should be defined
+
When trace output is desired, debug is to be defined
when the module m is compiled:
% erlc -Ddebug m.erl
@@ -215,18 +224,18 @@ or
1> c(m, {d, debug}).
{ok,m}
- ?LOG(Arg) will then expand to a call to io:format/2
+
?LOG(Arg) is then expanded to a call to io:format/2
and provide the user with some simple trace output.
The construction
The feature was added in Erlang 5.0/OTP R7.
-Example:
+Example:
-define(TESTCALL(Call), io:format("Call ~s: ~w~n", [??Call, Call])).
@@ -236,7 +245,7 @@ or
io:format("Call ~s: ~w~n",["myfunction ( 1 , 2 )",myfunction(1,2)]),
io:format("Call ~s: ~w~n",["you : function ( 2 , 1 )",you:function(2,1)]).
- That is, a trace output with both the function called and
+
That is, a trace output, with both the function called and
the resulting value.
Erlang code is divided into modules. A module consists of a sequence of attributes and function declarations, each - terminated by period (.). Example:
+ terminated by period (.). +Example:
-module(m). % module attribute -export([fact/1]). % module attribute @@ -42,50 +43,52 @@ fact(N) when N>0 -> % beginning of function declaration N * fact(N-1); % | fact(0) -> % | 1. % end of function declaration-
See the
For a description of function declarations, see
+
A module attribute defines a certain property of a - module. A module attribute consists of a tag and a value.
+ module. +A module attribute consists of a tag and a value:
-Tag(Value).
Any module attribute can be specified. The attributes are stored
in the compiled code and can be retrieved by calling
-
There are several module attributes with predefined meanings, - some of which have arity two, but user-defined module +
Several module attributes have predefined meanings. + Some of them have arity two, but user-defined module attributes must have arity one.
Pre-defined module attributes should be placed before any +
Pre-defined module attributes is to be placed before any function declaration.
Module declaration, defining the name of the module.
- The name
This attribute should be specified first and is the only - attribute which is mandatory.
+This attribute is to be specified first and is the only + mandatory attribute.
Exported functions. Specifies which of the functions - defined within the module that are visible outside +
Exported functions. Specifies which of the functions, + defined within the module, that are visible from outside the module.
Imported functions. Imported functions can be called - the same way as local functions, that is without any module +
Imported functions. Can be called + the same way as local functions, that is, without any module prefix.
Compiler options.
Compiler options.
Module version.
If this attribute is not specified, the version defaults to the MD5 checksum of the module.
Names a function that should be run automatically when a
- module a loaded. See
This attribute names a function that is to be run
+ automatically when a
+ module is loaded. For more information, see
+
-behaviour(Behaviour).
The atom
The spelling
The callback functions of the module can be specified either
directly by the exported function
-callback Name(Arguments) -> Result.-
where
Here,
The same syntax as for module attributes is used by +
The same syntax as for module attributes is used for record definitions:
-record(Record,Fields).@@ -163,7 +176,7 @@ behaviour_info(callbacks) -> Callbacks.
The same syntax as for module attributes is used by the preprocessor, which supports file inclusion, macros, and conditional compilation:
@@ -171,7 +184,7 @@ behaviour_info(callbacks) -> Callbacks. -include("SomeFile.hrl"). -define(Macro,Replacement). -Read more in
Read more in
-file(File, Line).-
This attribute is used by tools such as Yecc to inform the - compiler that the source program was generated by another tool - and indicates the correspondence of source files to lines of - the original user-written file from which the source program - was produced.
+This attribute is used by tools, such as Yecc, to inform the + compiler that the source program is generated by another tool. + It also indicates the correspondence of source files to lines of + the original user-written file, from which the source program + is produced.
A similar syntax as for module attributes is used for - specifying types and function specifications. + specifying types and function specifications:
-type my_type() :: atom() | integer(). @@ -200,32 +213,36 @@ behaviour_info(callbacks) -> Callbacks.
The description is based on
Comments may be placed anywhere in a module except within strings - and quoted atoms. The comment begins with the character "%", +
Comments can be placed anywhere in a module except within strings + and quoted atoms. A comment begins with the character "%", continues up to, but does not include the next end-of-line, and - has no effect. Note that the terminating end-of-line has + has no effect. Notice that the terminating end-of-line has the effect of white space.
The compiler automatically inserts the two special, exported
- functions into each module:
These functions can be called to retrieve information + about the module.
The
The The call The call The following values are allowed for Return an atom representing the module name. Returns an atom representing the module name. Return a list of Returns a list of The list of attributes will be empty if
- the module has been stripped with
- The list of attributes becomes empty if
+ the module is stripped with the
+ Return a list of tuples containing information about
- how the module was compiled. This list will be empty if
- the module has been stripped with
- Returns a list of tuples with information about
+ how the module was compiled. This list is empty if
+ the module has been stripped with the
+ Return a binary representing the MD5 checksum of the module. Returns a binary representing the MD5 checksum of the module. Return a list of Returns a list of Return a list of Returns a list of
Examples:
+Examples:
1> X. ** 1: variable 'X' is unbound ** diff --git a/system/doc/reference_manual/ports.xml b/system/doc/reference_manual/ports.xml index 621af10624..e5dc99641b 100644 --- a/system/doc/reference_manual/ports.xml +++ b/system/doc/reference_manual/ports.xml @@ -4,7 +4,7 @@diff --git a/system/doc/reference_manual/processes.xml b/system/doc/reference_manual/processes.xml index 95ae0672ec..32af6d4480 100644 --- a/system/doc/reference_manual/processes.xml +++ b/system/doc/reference_manual/processes.xml @@ -4,7 +4,7 @@ - - 2004 2013 +2004 2015 Ericsson AB. All Rights Reserved. @@ -28,9 +28,12 @@ ports.xml Examples of how to use ports and port drivers can be found in - Interoperability Tutorial. The BIFs mentioned are as usual - documented in
+erlang(3) .Examples of how to use ports and port drivers are provided in +
+ Interoperability Tutorial . + For information about the BIFs mentioned, see the +erlang(3) manual + page in ERTS.Ports @@ -39,29 +42,34 @@ provide a byte-oriented interface to an external program. When a port has been created, Erlang can communicate with it by sending and receiving lists of bytes, including binaries. -The Erlang process which creates a port is said to be +
The Erlang process creating a port is said to be the port owner, or the connected process of - the port. All communication to and from the port should go via - the port owner. If the port owner terminates, so will the port + the port. All communication to and from the port must go through + the port owner. If the port owner terminates, so does the port (and the external program, if it is written correctly).
The external program resides in another OS process. By default, - it should read from standard input (file descriptor 0) and write + it reads from standard input (file descriptor 0) and writes to standard output (file descriptor 1). The external program - should terminate when the port is closed.
+ is to terminate when the port is closed.Port Drivers -It is also possible to write a driver in C according to certain +
It is possible to write a driver in C according to certain principles and dynamically link it to the Erlang runtime system. The linked-in driver looks like a port from the Erlang programmer's point of view and is called a port driver.
- -An erroneous port driver will cause the entire Erlang runtime +
An erroneous port driver causes the entire Erlang runtime system to leak memory, hang or crash.
Port drivers are documented in
+erl_driver(4) , -driver_entry(1) anderl_ddll(3) .For information about port drivers, see the +
erl_driver(4) + manual page in ERTS, +driver_entry(1) + manual page in ERTS, and +erl_ddll(3) + manual page in Kernel.@@ -70,53 +78,74 @@
-
- | open_port(PortName, PortSettings Returns a port identifier | +Port as the result of opening a new Erlang port. Messages can be sent to and received from a port identifier, just like a pid. Port identifiers can also be linked to or registered under a name usinglink/1 andregister/2 .Returns a port identifier + | Port as the result of opening a new Erlang port. + Messages can be sent to, and received from, a port identifier, + just like a pid. Port identifiers can also be linked to + usinglink/1 , or registered under a name using +register/2 .Port Creation BIF. +Port Creation BIF + The external program runs outside the Erlang workspace, unless a + port driver with the name
PortName is usually a tuple{spawn,Command} , where the stringCommand is the name of the external program. - The external program runs outside the Erlang workspace unless a - port driver with the nameCommand is found. If found, that - driver is started.Command is found. IfCommand + is found, that driver is started.
PortSettings is a list of settings (options) for the port. - The list typically contains at least a tuple{packet,N} + The list typically contains at least a tuple{packet,N} , which specifies that data sent between the port and the external program are preceded by an N-byte length indicator. Valid values - for N are 1, 2 or 4. If binaries should be used instead of lists + for N are 1, 2, or 4. If binaries are to be used instead of lists of bytes, the optionbinary must be included.The port owner
-Pid can communicate with the portPort by sending and receiving messages. (In fact, any process can send the messages to the port, but the port owner must be identified in the message).As of OTP-R16 messages sent to ports are delivered truly +
As of Erlang/OTP R16, messages sent to ports are delivered truly asynchronously. The underlying implementation previously delivered messages to ports synchronously. Message passing has - however always been documented as an asynchronous operation, so - this should not be an issue for an Erlang program communicating - with ports, unless false assumptions about ports has been made.
-Below,
+ however always been documented as an asynchronous operation. Hence, + this is not to be an issue for an Erlang program communicating + with ports, unless false assumptions about ports have been made. +Data must be an I/O list. An I/O list is a binary - or a (possibly deep) list of binaries or integers in the range - 0..255.In the following tables of examples,
Data must be an I/O list. + An I/O list is a binary or a (possibly deep) list of binaries + or integers in the range 0..255:+
++
Message | +Description | +|
- | {Pid,{command,Data}} Sends | +Data to the port.Sends | Data to the port.|
- | {Pid,close} Closes the port. Unless the port is already closed, the port replies with | +{Port,closed} when all buffers have been flushed and the port really closes.Closes the port. Unless the + port is already closed, the port replies with + | {Port,closed} when all buffers have been flushed + and the port really closes.-
- | {Pid,{connect,NewPid}} Sets the port owner of | +Port toNewPid . Unless the port is already closed, the port replies with{Port,connected} to the old port owner. Note that the old port owner is still linked to the port, but the new port owner is not.Sets the port owner of + | Port toNewPid . Unless the port is already closed, + the port replies with{Port,connected} to the old + port owner. Note that the old port owner is still linked + to the port, but the new port owner is not.Messages Sent To a Port. +Messages Sent To a Port +
+
Message | +Description | +|
- | {Port,{data,Data}} + | Data is received from the external program. | Data is received from the external program.|
@@ -124,20 +153,24 @@ | {Port,closed} |
- | {Port,connected} Reply to | +Port ! {Pid,{connect,NewPid}} Reply to | Port ! {Pid,{connect,NewPid}} .-
| {'EXIT',Port,Reason} If the port has terminated for some reason. | Messages Received From a Port. +Messages Received From a Port Instead of sending and receiving messages, there are also a - number of BIFs that can be used.
+ number of BIFs that can be used:+
-+
Port BIF | +Description | +|
- | port_command(Port,Data) Sends | +Data to the port.Sends | Data to the port.|
@@ -145,7 +178,10 @@ | port_close(Port) |
- | port_connect(Port,NewPid) Sets the port owner of | +Port toNewPid . The old port ownerPid stays linked to the port and have to callunlink(Port) if this is not desired.Sets the port owner of + | Port toNewPid . The old port ownerPid + stays linked to the port and must callunlink(Port) + if this is not desired.-
@@ -155,9 +191,9 @@ | erlang:port_info(Port,Item) | erlang:ports() Returns a list of all ports on the current node. | Port BIFs. +Port BIFs There are some additional BIFs that only apply to port drivers: +
Some additional BIFs that apply to port drivers:
port_control/3 anderlang:port_call/3 .- 2003 2013 +2003 2015 Ericsson AB. All Rights Reserved. @@ -32,8 +32,8 @@ @@ -46,10 +46,10 @@ spawn(Module, Name, Args) -> pid() Args = [Arg1,...,ArgN] ArgI = term() Processes Erlang is designed for massive concurrency. Erlang processes are - light-weight (grow and shrink dynamically) with small memory - footprint, fast to create and terminate and the scheduling + lightweight (grow and shrink dynamically) with small memory + footprint, fast to create and terminate, and the scheduling overhead is low.
The new process will start executing in
-
The new process starts executing in
+
There exist a number of other
There exist a number of other
When a process terminates, it always terminates with an - exit reason. The reason may be any term.
+ exit reason. The reason can be any term.A process is said to terminate normally, if the exit
reason is the atom
A process terminates with exit reason
A process terminates with an exit reason
A process can terminate itself by calling one of the BIFs
-
A process can terminate itself by calling one of the + following BIFs:
+The process then terminates with reason
A process may also be terminated if it receives an exit signal +
A process can also be terminated if it receives an exit signal
with another exit reason than
Two processes can be linked to each other. A link
between two processes
Links are bidirectional and there can only be one link between
two processes. Repeated calls to
A link can be removed by calling the BIF
Links are used to monitor the behaviour of other processes, see
-
Erlang has a built-in feature for error handling between - processes. Terminating processes will emit exit signals to all - linked processes, which may terminate as well or handle the exit + processes. Terminating processes emit exit signals to all + linked processes, which can terminate as well or handle the exit in some way. This feature can be used to build hierarchical program structures where some processes are supervising other - processes, for example restarting them if they terminate + processes, for example, restarting them if they terminate abnormally.
-Refer to OTP Design Principles for more information about - OTP supervision trees, which uses this feature.
+See
When a process terminates, it will terminate with an exit reason as explained in
When a process terminates, it terminates with an
+ exit reason as explained in
A process can also call the function
A process can be set to trap exit signals by calling:
process_flag(trap_exit, true)-
When a process is trapping exits, it will not terminate when +
When a process is trapping exits, it does not terminate when
an exit signal is received. Instead, the signal is transformed
- into a message
An exception to the above is if the exit reason is
If
Monitors are unidirectional. Repeated calls to
-
A monitor can be removed by calling
It is possible to create monitors for processes with registered +
Monitors can be created for processes with registered names, also at other nodes.
diff --git a/system/doc/reference_manual/records.xml b/system/doc/reference_manual/records.xml index 04766531df..3294255af9 100644 --- a/system/doc/reference_manual/records.xml +++ b/system/doc/reference_manual/records.xml @@ -32,16 +32,19 @@ elements. It has named fields and is similar to a struct in C. Record expressions are translated to tuple expressions during compilation. Therefore, record expressions are not understood by - the shell unless special actions are taken. SeeMore record examples can be found in Programming Examples.
+ the shell unless special actions are taken. For details, see the +More examples are provided in
+
A record definition consists of the name of the record,
followed by the field names of the record. Record and field names
must be atoms. Each field can be given an optional default value.
- If no default value is supplied,
-record(Name, {Field1 [= Value1], ... @@ -60,17 +63,18 @@ the corresponding expressionExprI :#Name{Field1=Expr1,...,FieldK=ExprK}-The fields may be in any order, not necessarily the same order as +
The fields can be in any order, not necessarily the same order as in the record definition, and fields can be omitted. Omitted - fields will get their respective default value instead.
-If several fields should be assigned the same value, + fields get their respective default value instead.
+If several fields are to be assigned the same value, the following construction can be used:
#Name{Field1=Expr1,...,FieldK=ExprK, _=ExprL}-Omitted fields will then get the value of evaluating
ExprL +Omitted fields then get the value of evaluating
+ patterns for ETS and Mnesia match functions. +ExprL instead of their default values. This feature was added in Erlang 5.1/OTP R8 and is primarily intended to be used to create - patterns for ETS and Mnesia match functions. Example:Example:
-record(person, {name, phone, address}). @@ -84,13 +88,13 @@ lookup(Name, Tab) ->Accessing Record Fields Expr#Name.Field-Returns the value of the specified field.
Expr should +Returns the value of the specified field.
Expr is to evaluate to aName record.The following expression returns the position of the specified field in the tuple representation of the record:
#Name.Field-Example:
+Example:
-record(person, {name, phone, address}). @@ -104,8 +108,8 @@ lookup(Name, List) ->Updating Records Expr#Name{Field1=Expr1,...,FieldK=ExprK}-
Expr should evaluate to aName record. Returns a - copy of this record, with the value of each specified field +@@ -116,17 +120,17 @@ Expr#Name{Field1=Expr1,...,FieldK=ExprK}
Expr is to evaluate to aName record. A + copy of this record is returned, with the value of each specified fieldFieldI changed to the value of evaluating the corresponding expressionExprI . All other fields retain their old values.Records in Guards Since record expressions are expanded to tuple expressions, creating records and accessing record fields are allowed in - guards. However all subexpressions, for example for field - initiations, must of course be valid guard expressions as well. - Examples:
+ guards. However all subexpressions, for example, for field + initiations, must be valid guard expressions as well. +Examples:
handle(Msg, State) when Msg==#msg{to=void, no=3} -> ... handle(Msg, State) when State#state.running==true -> ...
-There is also a type test BIF
+is_record(Term, RecordTag) . - Example:There is also a type test BIF
+is_record(Term, RecordTag) .Example:
is_person(P) when is_record(P, person) -> true; @@ -136,18 +140,18 @@ is_person(_P) ->Records in Patterns -A pattern that will match a certain record is created the same +
A pattern that matches a certain record is created in the same way as a record is created:
#Name{Field1=Expr1,...,FieldK=ExprK}-In this case, one or more of
Expr1 ...ExprK may be +In this case, one or more of
Expr1 ...ExprK can be unbound variables.- Nested records -Beginning with R14 parentheses when accessing or updating nested - records can be omitted. Assuming we have the following record +
Nested Records +Beginning with Erlang/OTP R14, parentheses when accessing or updating nested + records can be omitted. Assume the following record definitions:
-record(nrec0, {name = "nested0"}). @@ -156,12 +160,12 @@ is_person(_P) -> N2 = #nrec2{},-Before R14 you would have needed to use parentheses as following:
+Before R14, parentheses were needed as follows:
"nested0" = ((N2#nrec2.nrec1)#nrec1.nrec0)#nrec0.name, N0n = ((N2#nrec2.nrec1)#nrec1.nrec0)#nrec0{name = "nested0a"},-Since R14 you can also write:
+Since R14, the following can also be written:
"nested0" = N2#nrec2.nrec1#nrec1.nrec0#nrec0.name, N0n = N2#nrec2.nrec1#nrec1.nrec0#nrec0{name = "nested0a"},@@ -170,23 +174,23 @@ N0n = N2#nrec2.nrec1#nrec1.nrec0#nrec0{name = "nested0a"},Internal Representation of Records Record expressions are translated to tuple expressions during - compilation. A record defined as
+ compilation. A record defined as:-record(Name, {Field1,...,FieldN}).-is internally represented by the tuple
+is internally represented by the tuple:
{Name,Value1,...,ValueN}-where each
+ValueI is the default value forFieldI .Here each
ValueI is the default value forFieldI .To each module using records, a pseudo function is added during compilation to obtain information about records:
record_info(fields, Record) -> [Field] record_info(size, Record) -> Size-
Size is the size of the tuple representation, that is +
Size is the size of the tuple representation, that is, one more than the number of fields.In addition,
+ representation of#Record.Name returns the index in the tuple - representation ofName of the recordRecord . -Name must be an atom.Name of the recordRecord . +
Name must be an atom.
Erlang is a dynamically typed language. Still, it comes with a notation for declaring sets of Erlang terms to form a particular - type, effectively forming a specific sub-type of the set of all + type. This effectively forms specific subtypes of the set of all Erlang terms.
Subsequently, these types can be used to specify types of record fields - and the argument and return types of functions. -
-
- Type information can be used to document function interfaces,
- provide more information for bug detection tools such as
+ Type information can be used for the following:
+It is expected that the type language described in this section
+ supersedes and replaces the purely comment-based
Types describe sets of Erlang terms.
- Types consist and are built from a set of predefined types
- (e.g.
- For integers and atoms, we allow for singleton types (e.g. the integers
-
atom() | 'bar' | integer() | 42@@ -79,13 +82,13 @@
atom() | integer()
- Because of sub-type relations that exist between types, types
- form a lattice where the topmost element,
- The set of predefined types and the syntax for types is given below: + The set of predefined types and the syntax for types follows:
The general form of bitstrings is<<_:M, _:_*N>> , whereM andN are positive integers. It denotes a - bitstring that isM + (k*N) bits long (i.e., a bitstring that + bitstring that isM + (k*N) bits long (that is, a bitstring that starts withM bits and continues withk segments ofN bits each, wherek is also a positive integer). The notations<<_:_*N>> ,<<_:M>> , and<<>> are convenient shorthands for the cases - thatM ,N , or both, respectively, are zero. + thatM orN , or both, are zero.Because lists are commonly used, they have shorthand type notations. The types
list(T) andnonempty_list(T) have the shorthands[T] and[T,...] , respectively. - The only difference between the two shorthands is that[T] may be an - empty list but[T,...] may not. + The only difference between the two shorthands is that[T] can be an + empty list but[T,...] cannot.- Notice that the shorthand for
@@ -172,7 +175,7 @@list() , i.e. the list of + Notice that the shorthand forlist() , that is, the list of elements of unknown type, is[_] (or[any()] ), not[] . The notation[] specifies the singleton type for the empty list.
In addition, the following three built-in types exist and can be @@ -245,7 +249,8 @@
@@ -278,109 +284,118 @@ define the set of Erlang terms one would expect.
- Also for convenience, we allow for record notation to be used. - Records are just shorthands for the corresponding tuples. + Also for convenience, record notation is allowed to be used. + Records are shorthands for the corresponding tuples:
Record :: #Erlang_Atom{} | #Erlang_Atom{Fields}
- Records have been extended to possibly contain type information.
- This is described in the sub-section
Map types, both
No type information of maps pairs, only the containing map types, are used by Dialyzer in OTP 17.
+Map types, both
No type information of maps pairs, only the containing map types, + are used by Dialyzer in OTP 17.
As seen, the basic syntax of a type is an atom followed by closed
- parentheses. New types are declared using '-type' and '-opaque'
+ parentheses. New types are declared using
-type my_struct_type() :: Type. -opaque my_opaq_type() :: Type.
- where the type name is an atom (
For module-local types, the restriction that their definition exists in the module is enforced by the compiler and results in a - compilation error. (A similar restriction currently exists for records.) -
+ compilation error. (A similar restriction currently exists for records.)Type declarations can also be parameterized by including type variables between the parentheses. The syntax of type variables is the same as - Erlang variables (starts with an upper case letter). - Naturally, these variables can - and should - appear on the RHS of the - definition. A concrete example appears below: + Erlang variables, that is, starts with an upper-case letter. + Naturally, these variables can - and is to - appear on the RHS of the + definition. A concrete example follows:
-type orddict(Key, Val) :: [{Key, Val}].
- A module can export some types in order to declare that other modules + A module can export some types to declare that other modules are allowed to refer to them as remote types. - This declaration has the following form: + This declaration has the following form:
-export_type([T1/A1, ..., Tk/Ak]).- where the Ti's are atoms (the name of the type) and the Ai's are their - arguments. An example is given below: +
Here the Ti's are atoms (the name of the type) and the Ai's are their + arguments
+Example:
-export_type([my_struct_type/0, orddict/2]).- Assuming that these types are exported from module
Assuming that these types are exported from module
mod:my_struct_type() mod:orddict(atom(), term())- One is not allowed to refer to types which are not declared as exported. +
It is not allowed to refer to types that are not declared as exported.
Types declared as
- The types of record fields can be specified in the declaration of the - record. The syntax for this is: + The types of record fields can be specified in the declaration of the + record. The syntax for this is as follows:
-record(rec, {field1 :: Type1, field2, field3 :: Type3}).
For fields without type annotations, their type defaults to any(). - I.e., the above is a shorthand for: + That is, the previous example is a shorthand for the following:
-record(rec, {field1 :: Type1, field2 :: any(), field3 :: Type3}).
In the presence of initial values for fields, - the type must be declared after the initialization as in the following: + the type must be declared after the initialization, as follows:
-record(rec, {field1 = [] :: Type1, field2, field3 = 42 :: Type3}).
- Naturally, the initial values for fields should be compatible
- with (i.e. 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
Any record, containing type information or not, once defined, - can be used as a type using the syntax: + can be used as a type using the following syntax:
#rec{}
In addition, the record fields can be further specified when using - a record type by adding type information about the field in - the following manner: + a record type by adding type information about the field + as follows:
#rec{some_field :: Type}
@@ -414,16 +429,16 @@
A specification (or contract) for a function is given using the new
- compiler attribute
-spec Module:Function(ArgType1, ..., ArgTypeN) -> ReturnType.
- The arity of the function has to match the number of arguments, - or else a compilation error occurs. + The arity of the function must match the number of arguments, + else a compilation error occurs.
This form can also be used in header files (.hrl) to declare type @@ -432,7 +447,7 @@ explicitly) import these functions.
- For most uses within a given module, the following shorthand suffices: + Within a given module, the following shorthand suffice in most cases:
-spec Function(ArgType1, ..., ArgTypeN) -> ReturnType.@@ -450,8 +465,8 @@ ; (T4, T5) -> T6.
A current restriction, which currently results in a warning - (OBS: not an error) by the compiler, is that the domains of - the argument types cannot be overlapping. + (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:
@@ -466,41 +481,43 @@-spec id(X) -> X.- However, note that the above specification does not restrict the input - and output type in any way. - We can constrain these types by guard-like subtype constraints + Notice that the above specification does not restrict the input + and output type in any way. + These types can be constrained by guard-like subtype constraints and provide bounded quantification:
-spec id(X) -> X when X :: tuple().Currently, the
:: constraint (read asis_subtype ) is - the only guard constraint which can be used in the'when' + the only guard constraint that can be used in the'when' part of a'-spec' attribute.- The above function specification, using multiple occurrences of - the same type variable, provides more type information than the - function specification below where the type variables are missing: + The above function specification uses multiple occurrences of + the same type variable. That provides more type information than the + following function specification, where the type variables are missing:
-spec id(tuple()) -> tuple().The latter specification says that the function takes some tuple - and returns some tuple, while the one with the
X type + and returns some tuple. The specification with theX type variable specifies that the function takes a tuple and returns the same tuple.- However, it's up to the tools that process the specs to choose - whether to take this extra information into account or ignore it. + However, it is up to the tools that process the specificationss + to choose whether to take this extra information into account + or not.
- The scope of an
:: constraint is the -(...) -> RetType - specification after which it appears. To avoid confusion, - we suggest that different variables are used in different - constituents of an overloaded contract as in the example below: + The scope of a:: constraint is the +(...) -> RetType + specification after which it appears. To avoid confusion, + it is suggested that different variables are used in different + constituents of an overloaded contract, as shown in the + following example:-spec foo({X, integer()}) -> X when X :: atom() @@ -511,19 +528,20 @@-spec id(X) -> X when is_subtype(X, tuple()).- but its use is discouraged. It will be taken out in a future + but its use is discouraged. It will be removed in a future Erlang/OTP release.
Some functions in Erlang are not meant to return; either because they define servers or because they are used to - throw exceptions as the function below: + throw exceptions, as in the following function:
my_error(Err) -> erlang:throw({error, Err}).- For such functions we recommend the use of the special
no_return() - type for their "return", via a contract of the form: + For such functions, it is recommended to use the special +no_return() type for their "return", through a contract + of the following form:-spec my_error(term()) -> no_return().