aboutsummaryrefslogtreecommitdiffstats
path: root/system/doc/reference_manual/expressions.xml
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2017-08-30 20:55:08 +0200
committerSverker Eriksson <[email protected]>2017-08-30 20:55:08 +0200
commit7c67bbddb53c364086f66260701bc54a61c9659c (patch)
tree92ab0d4b91d5e2f6e7a3f9d61ea25089e8a71fe0 /system/doc/reference_manual/expressions.xml
parent97dc5e7f396129222419811c173edc7fa767b0f8 (diff)
parent3b7a6ffddc819bf305353a593904cea9e932e7dc (diff)
downloadotp-7c67bbddb53c364086f66260701bc54a61c9659c.tar.gz
otp-7c67bbddb53c364086f66260701bc54a61c9659c.tar.bz2
otp-7c67bbddb53c364086f66260701bc54a61c9659c.zip
Merge tag 'OTP-19.0' into sverker/19/binary_to_atom-utf8-crash/ERL-474/OTP-14590
Diffstat (limited to 'system/doc/reference_manual/expressions.xml')
-rw-r--r--system/doc/reference_manual/expressions.xml939
1 files changed, 625 insertions, 314 deletions
diff --git a/system/doc/reference_manual/expressions.xml b/system/doc/reference_manual/expressions.xml
index 357f89f731..355fd3cfef 100644
--- a/system/doc/reference_manual/expressions.xml
+++ b/system/doc/reference_manual/expressions.xml
@@ -1,23 +1,24 @@
-<?xml version="1.0" encoding="latin1" ?>
+<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE chapter SYSTEM "chapter.dtd">
<chapter>
<header>
<copyright>
- <year>2003</year><year>2012</year>
+ <year>2003</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
</legalnotice>
@@ -28,13 +29,17 @@
<rev></rev>
<file>expressions.xml</file>
</header>
- <p>In this chapter, all valid Erlang expressions are listed.
+ <p>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: <seealso marker="macros">Macros</seealso> and
- <seealso marker="records">Records</seealso>.</p>
+ separate sections:
+ </p>
+ <list type="bulleted">
+ <item><p><seealso marker="macros">Preprocessor</seealso></p></item>
+ <item><p><seealso marker="records">Records</seealso></p></item>
+ </list>
<section>
<title>Expression Evaluation</title>
@@ -48,15 +53,15 @@ Expr1 + Expr2</code>
performed.</p>
<p>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 <c>badarg</c> run-time error.</p>
+ applied to numbers. An argument of the wrong type causes
+ a <c>badarg</c> runtime error.</p>
</section>
<section>
<marker id="term"></marker>
<title>Terms</title>
<p>The simplest form of expression is a term, that is an integer,
- float, atom, string, list or tuple.
+ float, atom, string, list, map, or tuple.
The return value is the term itself.</p>
</section>
@@ -65,9 +70,10 @@ Expr1 + Expr2</code>
<p>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.</p>
- <p>Variables start with an uppercase letter or underscore (_)
- and may contain alphanumeric characters, underscore and @.
- Examples:</p>
+ <p>Variables start with an uppercase letter or underscore (_).
+ Variables can contain alphanumeric characters, underscore and <c>@</c>.
+ </p>
+ <p><em>Examples:</em></p>
<pre>
X
Name1
@@ -77,18 +83,20 @@ _
_Height</pre>
<p>Variables are bound to values using
<seealso marker="patterns">pattern matching</seealso>. Erlang
- uses <em>single assignment</em>, a variable can only be bound
+ uses <em>single assignment</em>, that is, a variable can only be bound
once.</p>
<p>The <em>anonymous variable</em> is denoted by underscore (_) and
can be used when a variable is required but its value can be
- ignored. Example:</p>
+ ignored.</p>
+ <p><em>Example:</em></p>
<pre>
[H|_] = [1,2,3]</pre>
- <p>Variables starting with underscore (_), for example
+ <p>Variables starting with underscore (_), for example,
<c>_Height</c>, are normal variables, not anonymous. They are
- however ignored by the compiler in the sense that they will not
- generate any warnings for unused variables. Example: The following
- code</p>
+ however ignored by the compiler in the sense that they do not
+ generate any warnings for unused variables.</p>
+ <p><em>Example:</em></p>
+ <p>The following code:</p>
<pre>
member(_, []) ->
[].</pre>
@@ -96,36 +104,37 @@ member(_, []) ->
<pre>
member(Elem, []) ->
[].</pre>
- <p>This will however cause a warning for an unused variable
+ <p>This causes a warning for an unused variable,
<c>Elem</c>, if the code is compiled with the flag
<c>warn_unused_vars</c> set. Instead, the code can be rewritten
to:</p>
<pre>
member(_Elem, []) ->
[].</pre>
- <p>Note that since variables starting with an underscore are
- not anonymous, this will match:</p>
+ <p>Notice that since variables starting with an underscore are
+ not anonymous, this matches:</p>
<pre>
{_,_} = {1,2}</pre>
- <p>But this will fail:</p>
+ <p>But this fails:</p>
<pre>
{_N,_N} = {1,2}</pre>
<p>The scope for a variable is its function clause.
Variables bound in a branch of an <c>if</c>, <c>case</c>,
or <c>receive</c> expression must be bound in all branches
- to have a value outside the expression, otherwise they
- will be regarded as 'unsafe' outside the expression.</p>
+ to have a value outside the expression. Otherwise they
+ are regarded as 'unsafe' outside the expression.</p>
<p>For the <c>try</c> expression introduced in
- Erlang 5.4/OTP-R10B, variable scoping is limited so that
+ Erlang 5.4/OTP R10B, variable scoping is limited so that
variables bound in the expression are always 'unsafe' outside
- the expression. This will be improved.</p>
+ the expression. This is to be improved.</p>
</section>
<section>
<marker id="pattern"></marker>
<title>Patterns</title>
- <p>A pattern has the same structure as a term but may contain
- unbound variables. Example:</p>
+ <p>A pattern has the same structure as a term but can contain
+ unbound variables.</p>
+ <p><em>Example:</em></p>
<pre>
Name1
[H|T]
@@ -136,13 +145,13 @@ Name1
<section>
<title>Match Operator = in Patterns</title>
<p>If <c>Pattern1</c> and <c>Pattern2</c> are valid patterns,
- then the following is also a valid pattern:</p>
+ the following is also a valid pattern:</p>
<pre>
Pattern1 = Pattern2</pre>
<p>When matched against a term, both <c>Pattern1</c> and
- <c>Pattern2</c> will be matched against the term. The idea
- behind this feature is to avoid reconstruction of terms.
- Example:</p>
+ <c>Pattern2</c> are matched against the term. The idea
+ behind this feature is to avoid reconstruction of terms.</p>
+ <p><em>Example:</em></p>
<pre>
f({connect,From,To,Number,Options}, To) ->
Signal = {connect,From,To,Number,Options},
@@ -163,16 +172,20 @@ f(Signal, To) ->
<pre>
f("prefix" ++ Str) -> ...</pre>
<p>This is syntactic sugar for the equivalent, but harder to
- read</p>
+ read:</p>
<pre>
f([$p,$r,$e,$f,$i,$x | Str]) -> ...</pre>
</section>
<section>
<title>Expressions in Patterns</title>
- <p>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:</p>
+ <p>An arithmetic expression can be used within a pattern if
+ it meets both of the following two conditions:</p>
+ <list type="bulleted">
+ <item>It uses only numeric or bitwise operators.</item>
+ <item>Its value can be evaluated to a constant when complied.</item>
+ </list>
+ <p><em>Example:</em></p>
<pre>
case {Value, Result} of
{?THRESHOLD+1, ok} -> ...</pre>
@@ -182,21 +195,21 @@ case {Value, Result} of
<section>
<title>Match</title>
+ <p>The following matches <c>Expr1</c>, a pattern, against
+ <c>Expr2</c>:</p>
<pre>
Expr1 = Expr2</pre>
- <p>Matches <c>Expr1</c>, a pattern, against <c>Expr2</c>.
- If the matching succeeds, any unbound variable in the pattern
+ <p>If the matching succeeds, any unbound variable in the pattern
becomes bound and the value of <c>Expr2</c> is returned.</p>
- <p>If the matching fails, a <c>badmatch</c> run-time error will
- occur.</p>
- <p>Examples:</p>
+ <p>If the matching fails, a <c>badmatch</c> run-time error occurs.</p>
+ <p><em>Examples:</em></p>
<pre>
1> <input>{A, B} = {answer, 42}.</input>
{answer,42}
2> <input>A.</input>
answer
3> <input>{C, D} = [1, 2].</input>
-** exception error: no match of right hand side value [1,2]</pre>
+** exception error: no match of right-hand side value [1,2]</pre>
</section>
<section>
@@ -210,45 +223,45 @@ ExprM:ExprF(Expr1,...,ExprN)</pre>
<c>ExprF</c> must be an atom or an expression that evaluates to
an atom. The function is said to be called by using the
<em>fully qualified function name</em>. This is often referred
- to as a <em>remote</em> or <em>external function call</em>.
- Example:</p>
+ to as a <em>remote</em> or <em>external function call</em>.</p>
+ <p><em>Example:</em></p>
<code type="none">
lists:keysearch(Name, 1, List)</code>
<p>In the second form of function calls,
<c>ExprF(Expr1,...,ExprN)</c>, <c>ExprF</c> must be an atom or
evaluate to a fun.</p>
- <p>If <c>ExprF</c> is an atom the function is said to be called by
+ <p>If <c>ExprF</c> is an atom, the function is said to be called by
using the <em>implicitly qualified function name</em>. If the
function <c>ExprF</c> is locally defined, it is called.
- Alternatively if <c>ExprF</c> is explicitly imported from module
- <c>M</c>, <c>M:ExprF(Expr1,...,ExprN)</c> is called. If
+ Alternatively, if <c>ExprF</c> is explicitly imported from the
+ <c>M</c> module, <c>M:ExprF(Expr1,...,ExprN)</c> is called. If
<c>ExprF</c> is neither declared locally nor explicitly
imported, <c>ExprF</c> must be the name of an automatically
- imported BIF. Examples:</p>
+ imported BIF. </p>
+ <p><em>Examples:</em></p>
<code type="none">
handle(Msg, State)
spawn(m, init, [])</code>
- <p>Examples where ExprF is a fun:</p>
- <code type="none">
-Fun1 = fun(X) -> X+1 end
-Fun1(3)
-=> 4
-
-fun lists:append/2([1,2], [3,4])
-=> [1,2,3,4]</code>
-
- <p>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
- <seealso marker="code_loading">Compilation and Code Loading</seealso>.</p>
-
- <p>See also the chapter about
- <seealso marker="functions#eval">Function Evaluation</seealso>.</p>
+ <p><em>Examples</em> where <c>ExprF</c> is a fun:</p>
+ <pre>
+1> <input>Fun1 = fun(X) -> X+1 end,</input>
+<input>Fun1(3).</input>
+4
+2> <input>fun lists:append/2([1,2], [3,4]).</input>
+[1,2,3,4]
+3> </pre>
+
+ <p>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 <seealso marker="code_loading">Compilation and Code Loading
+ </seealso> and <seealso marker="functions#eval">
+ Function Evaluation</seealso>.</p>
<section>
- <title>Local Function Names Clashing With Auto-imported BIFs</title>
+ <title>Local Function Names Clashing With Auto-Imported BIFs</title>
<p>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 +273,9 @@ fun lists:append/2([1,2], [3,4])
<warning><p>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.</p>
<p>However, to avoid that old (pre R14) code changed its
@@ -272,8 +285,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:</p> </warning>
+ qualified function call. Otherwise you get a compilation
+ error. See the following example:</p> </warning>
<code type="none">
-export([length/1,f/1]).
@@ -283,16 +296,17 @@ fun lists:append/2([1,2], [3,4])
length([]) ->
0;
length([H|T]) ->
- 1 + length(T). %% Calls the local funtion length/1
+ 1 + length(T). %% Calls the local function length/1
f(X) when erlang:length(X) > 3 -> %% Calls erlang:length/1,
%% which is allowed in guards
long.</code>
<p>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.</p>
+ module at the same time:</p>
<code type="none">
-export([f/1]).
@@ -301,7 +315,7 @@ f(X) when erlang:length(X) > 3 -> %% Calls erlang:length/1,
-import(mod,[length/1]).
-f(X) when erlang:length(X) > 33 -> %% Calls erlang:lenght/1,
+f(X) when erlang:length(X) > 33 -> %% Calls erlang:length/1,
%% which is allowed in guards
erlang:length(X); %% Explicit call to erlang:length in body
@@ -310,10 +324,10 @@ f(X) ->
length(X). %% mod:length/1 is called</code>
- <p>For auto-imported BIFs added to Erlang in release R14A and thereafter,
+ <p>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 <c>-compile({no_auto_import,[F/A])</c>
- directive is not used, the compiler will issue a warning whenever
+ directive is not used, the compiler issues a warning whenever
the function is called in the module using the implicitly qualified
function name.</p>
</section>
@@ -330,15 +344,16 @@ if
BodyN
end</pre>
<p>The branches of an <c>if</c>-expression are scanned sequentially
- until a guard sequence <c>GuardSeq</c> which evaluates to true is
+ until a guard sequence <c>GuardSeq</c> that evaluates to true is
found. Then the corresponding <c>Body</c> (sequence of expressions
separated by ',') is evaluated.</p>
<p>The return value of <c>Body</c> is the return value of
the <c>if</c> expression.</p>
- <p>If no guard sequence is true, an <c>if_clause</c> run-time error
- will occur. If necessary, the guard expression <c>true</c> can be
+ <p>If no guard sequence is evaluated as true,
+ an <c>if_clause</c> run-time error
+ occurs. If necessary, the guard expression <c>true</c> can be
used in the last branch, as that guard sequence is always true.</p>
- <p>Example:</p>
+ <p><em>Example:</em></p>
<pre>
is_greater_than(X, Y) ->
if
@@ -367,8 +382,8 @@ end</pre>
<p>The return value of <c>Body</c> is the return value of
the <c>case</c> expression.</p>
<p>If there is no matching pattern with a true guard sequence,
- a <c>case_clause</c> run-time error will occur.</p>
- <p>Example:</p>
+ a <c>case_clause</c> run-time error occurs.</p>
+ <p><em>Example:</em></p>
<pre>
is_valid_signal(Signal) ->
case Signal of
@@ -389,15 +404,15 @@ Expr1 ! Expr2</pre>
<p>Sends the value of <c>Expr2</c> as a message to the process
specified by <c>Expr1</c>. The value of <c>Expr2</c> is also
the return value of the expression.</p>
- <p><c>Expr1</c> must evaluate to a pid, a registered name (atom) or
- a tuple <c>{Name,Node}</c>, where <c>Name</c> is an atom and
- <c>Node</c> a node name, also an atom.</p>
+ <p><c>Expr1</c> must evaluate to a pid, a registered name (atom), or
+ a tuple <c>{Name,Node}</c>. <c>Name</c> is an atom and
+ <c>Node</c> is a node name, also an atom.</p>
<list type="bulleted">
<item>If <c>Expr1</c> evaluates to a name, but this name is not
- registered, a <c>badarg</c> run-time error will occur.</item>
+ registered, a <c>badarg</c> run-time error occurs.</item>
<item>Sending a message to a pid never fails, even if the pid
identifies a non-existing process.</item>
- <item>Distributed message sending, that is if <c>Expr1</c>
+ <item>Distributed message sending, that is, if <c>Expr1</c>
evaluates to a tuple <c>{Name,Node}</c> (or a pid located at
another node), also never fails.</item>
</list>
@@ -420,14 +435,14 @@ end</pre>
the second, and so on. If a match succeeds and the optional
guard sequence <c>GuardSeq</c> is true, the corresponding
<c>Body</c> is evaluated. The matching message is consumed, that
- is removed from the mailbox, while any other messages in
+ is, removed from the mailbox, while any other messages in
the mailbox remain unchanged.</p>
<p>The return value of <c>Body</c> is the return value of
the <c>receive</c> expression.</p>
- <p><c>receive</c> never fails. Execution is suspended, possibly
- indefinitely, until a message arrives that does match one of
+ <p><c>receive</c> never fails. The execution is suspended, possibly
+ indefinitely, until a message arrives that matches one of
the patterns and with a true guard sequence. </p>
- <p>Example:</p>
+ <p><em>Example:</em></p>
<pre>
wait_for_onhook() ->
receive
@@ -438,7 +453,7 @@ wait_for_onhook() ->
B ! {busy, self()},
wait_for_onhook()
end.</pre>
- <p>It is possible to augment the <c>receive</c> expression with a
+ <p>The <c>receive</c> expression can be augmented with a
timeout:</p>
<pre>
receive
@@ -451,14 +466,14 @@ after
ExprT ->
BodyT
end</pre>
- <p><c>ExprT</c> should evaluate to an integer. The highest allowed
- value is 16#ffffffff, that is, the value must fit in 32 bits.
+ <p><c>ExprT</c> is to evaluate to an integer. The highest allowed
+ value is 16#FFFFFFFF, that is, the value must fit in 32 bits.
<c>receive..after</c> works exactly as <c>receive</c>, except
that if no matching message has arrived within <c>ExprT</c>
- milliseconds, then <c>BodyT</c> is evaluated instead and its
- return value becomes the return value of the <c>receive..after</c>
- expression.</p>
- <p>Example:</p>
+ milliseconds, then <c>BodyT</c> is evaluated instead. The
+ return value of <c>BodyT</c> then becomes the return value
+ of the <c>receive..after</c> expression.</p>
+ <p><em>Example:</em></p>
<pre>
wait_for_onhook() ->
receive
@@ -481,10 +496,10 @@ after
ExprT ->
BodyT
end</pre>
- <p>This construction will not consume any messages, only suspend
- execution in the process for <c>ExprT</c> milliseconds and can be
+ <p>This construction does not consume any messages, only suspends
+ execution in the process for <c>ExprT</c> milliseconds. This can be
used to implement simple timers.</p>
- <p>Example:</p>
+ <p><em>Example:</em></p>
<pre>
timer() ->
spawn(m, timer, [self()]).
@@ -498,12 +513,12 @@ timer(Pid) ->
<p>There are two special cases for the timeout value <c>ExprT</c>:</p>
<taglist>
<tag><c>infinity</c></tag>
- <item>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.</item>
+ <item>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.</item>
<tag>0</tag>
<item>If there is no matching message in the mailbox, the timeout
- will occur immediately.</item>
+ occurs immediately.</item>
</taglist>
</section>
@@ -518,64 +533,73 @@ Expr1 <input>op</input> Expr2</pre>
</row>
<row>
<cell align="left" valign="middle">==</cell>
- <cell align="left" valign="middle">equal to</cell>
+ <cell align="left" valign="middle">Equal to</cell>
</row>
<row>
<cell align="left" valign="middle">/=</cell>
- <cell align="left" valign="middle">not equal to</cell>
+ <cell align="left" valign="middle">Not equal to</cell>
</row>
<row>
<cell align="left" valign="middle">=&lt;</cell>
- <cell align="left" valign="middle">less than or equal to</cell>
+ <cell align="left" valign="middle">Less than or equal to</cell>
</row>
<row>
<cell align="left" valign="middle">&lt;</cell>
- <cell align="left" valign="middle">less than</cell>
+ <cell align="left" valign="middle">Less than</cell>
</row>
<row>
<cell align="left" valign="middle">&gt;=</cell>
- <cell align="left" valign="middle">greater than or equal to</cell>
+ <cell align="left" valign="middle">Greater than or equal to</cell>
</row>
<row>
<cell align="left" valign="middle">&gt;</cell>
- <cell align="left" valign="middle">greater than</cell>
+ <cell align="left" valign="middle">Greater than</cell>
</row>
<row>
<cell align="left" valign="middle">=:=</cell>
- <cell align="left" valign="middle">exactly equal to</cell>
+ <cell align="left" valign="middle">Exactly equal to</cell>
</row>
<row>
<cell align="left" valign="middle">=/=</cell>
- <cell align="left" valign="middle">exactly not equal to</cell>
+ <cell align="left" valign="middle">Exactly not equal to</cell>
</row>
<tcaption>Term Comparison Operators.</tcaption>
</table>
- <p>The arguments may be of different data types. The following
+ <p>The arguments can be of different data types. The following
order is defined:</p>
<pre>
-number &lt; atom &lt; reference &lt; fun &lt; port &lt; pid &lt; tuple &lt; list &lt; bit string</pre>
+number &lt; atom &lt; reference &lt; fun &lt; port &lt; pid &lt; tuple &lt; map &lt; nil &lt; list &lt; bit string</pre>
<p>Lists are compared element by element. Tuples are ordered by
size, two tuples with the same size are compared element by
element.</p>
+ <p>Maps are ordered by size, two maps with the same size are compared by keys in
+ ascending term order and then by values in key order.
+ In maps key order integers types are considered less than floats types.
+ </p>
<p>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 <c>=:=</c> or <c>=/=</c>. A float is more precise than
an integer until all significant figures of the float are to the left of
the decimal point. This happens when the float is larger/smaller than
+/-9007199254740992.0. The conversion strategy is changed
depending on the size of the float because otherwise comparison of large
floats and integers would lose their transitivity.</p>
- <p>Returns the Boolean value of the expression, <c>true</c> or
- <c>false</c>.</p>
- <p>Examples:</p>
+ <p>Term comparison operators return the Boolean value of the
+ expression, <c>true</c> or <c>false</c>.</p>
+
+ <p><em>Examples:</em></p>
<pre>
1> <input>1==1.0.</input>
true
2> <input>1=:=1.0.</input>
false
3> <input>1 > a.</input>
-false</pre>
+false
+4> <input>#{c => 3} > #{a => 1, b => 2}.</input>
+false
+4> <input>#{a => 1, b => 2} == #{a => 1.0, b => 2.0}.</input>
+true</pre>
</section>
<section>
@@ -585,19 +609,19 @@ false</pre>
Expr1 <input>op</input> Expr2</pre>
<table>
<row>
- <cell align="left" valign="middle"><em>op</em></cell>
+ <cell align="left" valign="middle"><em>Operator</em></cell>
<cell align="left" valign="middle"><em>Description</em></cell>
- <cell align="left" valign="middle"><em>Argument type</em></cell>
+ <cell align="left" valign="middle"><em>Argument Type</em></cell>
</row>
<row>
<cell align="left" valign="middle">+</cell>
- <cell align="left" valign="middle">unary +</cell>
- <cell align="left" valign="middle">number</cell>
+ <cell align="left" valign="middle">Unary +</cell>
+ <cell align="left" valign="middle">Number</cell>
</row>
<row>
<cell align="left" valign="middle">-</cell>
- <cell align="left" valign="middle">unary -</cell>
- <cell align="left" valign="middle">number</cell>
+ <cell align="left" valign="middle">Unary -</cell>
+ <cell align="left" valign="middle">Number</cell>
</row>
<row>
<cell align="left" valign="middle">+</cell>
@@ -607,62 +631,62 @@ Expr1 <input>op</input> Expr2</pre>
<row>
<cell align="left" valign="middle">-</cell>
<cell align="left" valign="middle">&nbsp;</cell>
- <cell align="left" valign="middle">number</cell>
+ <cell align="left" valign="middle">Number</cell>
</row>
<row>
<cell align="left" valign="middle">*</cell>
<cell align="left" valign="middle">&nbsp;</cell>
- <cell align="left" valign="middle">number</cell>
+ <cell align="left" valign="middle">Number</cell>
</row>
<row>
<cell align="left" valign="middle">/</cell>
- <cell align="left" valign="middle">floating point division</cell>
- <cell align="left" valign="middle">number</cell>
+ <cell align="left" valign="middle">Floating point division</cell>
+ <cell align="left" valign="middle">Number</cell>
</row>
<row>
<cell align="left" valign="middle">bnot</cell>
- <cell align="left" valign="middle">unary bitwise not</cell>
- <cell align="left" valign="middle">integer</cell>
+ <cell align="left" valign="middle">Unary bitwise NOT</cell>
+ <cell align="left" valign="middle">Integer</cell>
</row>
<row>
<cell align="left" valign="middle">div</cell>
- <cell align="left" valign="middle">integer division</cell>
- <cell align="left" valign="middle">integer</cell>
+ <cell align="left" valign="middle">Integer division</cell>
+ <cell align="left" valign="middle">Integer</cell>
</row>
<row>
<cell align="left" valign="middle">rem</cell>
- <cell align="left" valign="middle">integer remainder of X/Y</cell>
- <cell align="left" valign="middle">integer</cell>
+ <cell align="left" valign="middle">Integer remainder of X/Y</cell>
+ <cell align="left" valign="middle">Integer</cell>
</row>
<row>
<cell align="left" valign="middle">band</cell>
- <cell align="left" valign="middle">bitwise and</cell>
- <cell align="left" valign="middle">integer</cell>
+ <cell align="left" valign="middle">Bitwise AND</cell>
+ <cell align="left" valign="middle">Integer</cell>
</row>
<row>
<cell align="left" valign="middle">bor</cell>
- <cell align="left" valign="middle">bitwise or</cell>
- <cell align="left" valign="middle">integer</cell>
+ <cell align="left" valign="middle">Bitwise OR</cell>
+ <cell align="left" valign="middle">Integer</cell>
</row>
<row>
<cell align="left" valign="middle">bxor</cell>
- <cell align="left" valign="middle">arithmetic bitwise xor</cell>
- <cell align="left" valign="middle">integer</cell>
+ <cell align="left" valign="middle">Arithmetic bitwise XOR</cell>
+ <cell align="left" valign="middle">Integer</cell>
</row>
<row>
<cell align="left" valign="middle">bsl</cell>
- <cell align="left" valign="middle">arithmetic bitshift left</cell>
- <cell align="left" valign="middle">integer</cell>
+ <cell align="left" valign="middle">Arithmetic bitshift left</cell>
+ <cell align="left" valign="middle">Integer</cell>
</row>
<row>
<cell align="left" valign="middle">bsr</cell>
- <cell align="left" valign="middle">bitshift right</cell>
- <cell align="left" valign="middle">integer</cell>
+ <cell align="left" valign="middle">Bitshift right</cell>
+ <cell align="left" valign="middle">Integer</cell>
</row>
<tcaption>Arithmetic Operators.</tcaption>
</table>
- <p>Examples:</p>
+ <p><em>Examples:</em></p>
<pre>
1> <input>+1.</input>
1
@@ -697,28 +721,28 @@ Expr1 <input>op</input> Expr2</pre>
Expr1 <input>op</input> Expr2</pre>
<table>
<row>
- <cell align="left" valign="middle"><em>op</em></cell>
+ <cell align="left" valign="middle"><em>Operator</em></cell>
<cell align="left" valign="middle"><em>Description</em></cell>
</row>
<row>
<cell align="left" valign="middle">not</cell>
- <cell align="left" valign="middle">unary logical not</cell>
+ <cell align="left" valign="middle">Unary logical NOT</cell>
</row>
<row>
<cell align="left" valign="middle">and</cell>
- <cell align="left" valign="middle">logical and</cell>
+ <cell align="left" valign="middle">Logical AND</cell>
</row>
<row>
<cell align="left" valign="middle">or</cell>
- <cell align="left" valign="middle">logical or</cell>
+ <cell align="left" valign="middle">Logical OR</cell>
</row>
<row>
<cell align="left" valign="middle">xor</cell>
- <cell align="left" valign="middle">logical xor</cell>
+ <cell align="left" valign="middle">Logical XOR</cell>
</row>
<tcaption>Logical Operators.</tcaption>
</table>
- <p>Examples:</p>
+ <p><em>Examples:</em></p>
<pre>
1> <input>not true.</input>
false
@@ -737,28 +761,37 @@ true
<pre>
Expr1 orelse Expr2
Expr1 andalso Expr2</pre>
- <p>Expressions where <c>Expr2</c> is evaluated only if
- necessary. That is, <c>Expr2</c> is evaluated only if <c>Expr1</c>
- evaluates to <c>false</c> in an <c>orelse</c> expression, or only
- if <c>Expr1</c> evaluates to <c>true</c> in an <c>andalso</c>
- expression. Returns either the value of <c>Expr1</c> (that is,
+ <p><c>Expr2</c> is evaluated only if
+ necessary. That is, <c>Expr2</c> is evaluated only if:</p>
+ <list type="bulleted">
+ <item><p><c>Expr1</c> evaluates to <c>false</c> in an
+ <c>orelse</c> expression.</p>
+ </item>
+ </list>
+ <p>or</p>
+ <list type="bulleted">
+ <item><p><c>Expr1</c> evaluates to <c>true</c> in an
+ <c>andalso</c> expression.</p>
+ </item>
+ </list>
+ <p>Returns either the value of <c>Expr1</c> (that is,
<c>true</c> or <c>false</c>) or the value of <c>Expr2</c>
- (if <c>Expr2</c> was evaluated).</p>
+ (if <c>Expr2</c> is evaluated).</p>
- <p>Example 1:</p>
+ <p><em>Example 1:</em></p>
<pre>
case A >= -1.0 andalso math:sqrt(A+1) > B of</pre>
- <p>This will work even if <c>A</c> is less than <c>-1.0</c>,
+ <p>This works even if <c>A</c> is less than <c>-1.0</c>,
since in that case, <c>math:sqrt/1</c> is never evaluated.</p>
- <p>Example 2:</p>
+ <p><em>Example 2:</em></p>
<pre>
OnlyOne = is_atom(L) orelse
(is_list(L) andalso length(L) == 1),</pre>
- <p>From R13A, <c>Expr2</c> is no longer required to evaluate to a
- boolean value. As a consequence, <c>andalso</c> and <c>orelse</c>
+ <p>From Erlang/OTP R13A, <c>Expr2</c> is no longer required to evaluate to a
+ Boolean value. As a consequence, <c>andalso</c> and <c>orelse</c>
are now tail-recursive. For instance, the following function is
- tail-recursive in R13A and later:</p>
+ tail-recursive in Erlang/OTP R13A and later:</p>
<pre>
all(Pred, [Hd|Tail]) ->
@@ -774,11 +807,11 @@ Expr1 ++ Expr2
Expr1 -- Expr2</pre>
<p>The list concatenation operator <c>++</c> appends its second
argument to its first and returns the resulting list.</p>
- <p>The list subtraction operator <c>--</c> 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
+ <p>The list subtraction operator <c>--</c> 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.</p>
- <p>Example:</p>
+ <p><em>Example:</em></p>
<pre>
1> <input>[1,2,3]++[4,5].</input>
[1,2,3,4,5]
@@ -786,12 +819,257 @@ Expr1 -- Expr2</pre>
[3,1,2]</pre>
<warning><p>The complexity of <c>A -- B</c> is
- proportional to <c>length(A)*length(B)</c>, meaning that it
- will be very slow if both <c>A</c> and <c>B</c> are
+ proportional to <c>length(A)*length(B)</c>. That is, it
+ becomes very slow if both <c>A</c> and <c>B</c> are
long lists.</p></warning>
</section>
<section>
+ <marker id="map_expressions"></marker>
+ <title>Map Expressions</title>
+ <section>
+ <title>Creating Maps</title>
+ <p>
+ Constructing a new map is done by letting an expression <c>K</c> be associated with
+ another expression <c>V</c>:
+ </p>
+ <code>#{ K => V }</code>
+ <p>
+ New maps can include multiple associations at construction by listing every
+ association:
+ </p>
+ <code>#{ K1 => V1, .., Kn => Vn }</code>
+ <p>
+ An empty map is constructed by not associating any terms with each other:
+ </p>
+ <code>#{}</code>
+ <p>
+ All keys and values in the map are terms. Any expression is first evaluated and
+ then the resulting terms are used as <em>key</em> and <em>value</em> respectively.
+ </p>
+ <p>
+ Keys and values are separated by the <c>=></c> arrow and associations are
+ separated by a comma <c>,</c>.
+ </p>
+
+ <p>
+ <em>Examples:</em>
+ </p>
+ <code>
+M0 = #{}, % empty map
+M1 = #{a => &lt;&lt;"hello"&gt;&gt;}, % single association with literals
+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</code>
+ <p>
+ Here, <c>A</c> and <c>B</c> are any expressions and <c>M0</c> through <c>M4</c>
+ are the resulting map terms.
+ </p>
+ <p>
+ If two matching keys are declared, the latter key takes precedence.
+ </p>
+ <p>
+ <em>Example:</em>
+ </p>
+
+<pre>
+1> <input>#{1 => a, 1 => b}.</input>
+#{1 => b }
+2> <input>#{1.0 => a, 1 => b}.</input>
+#{1 => b, 1.0 => a}
+</pre>
+ <p>
+ 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 recently mentioned case of two matching keys.
+ </p>
+ </section>
+
+ <section>
+ <title>Updating Maps</title>
+ <p>
+ Updating a map has a similar syntax as constructing it.
+ </p>
+ <p>
+ 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:
+ </p>
+ <code>M#{ K => V }</code>
+ <p>
+ Here <c>M</c> is a term of type map and <c>K</c> and <c>V</c> are any expression.
+ </p>
+ <p>
+ If key <c>K</c> does not match any existing key in the map, a new association
+ is created from key <c>K</c> to value <c>V</c>.
+ </p>
+ <p> If key <c>K</c> matches an existing key in map <c>M</c>,
+ its associated value
+ is replaced by the new value <c>V</c>. In both cases, the evaluated map expression
+ returns a new map.
+ </p>
+ <p>
+ If <c>M</c> is not of type map, an exception of type <c>badmap</c> is thrown.
+ </p>
+ <p>
+ To only update an existing value, the following syntax is used:
+ </p>
+ <code>M#{ K := V } </code>
+ <p>
+ Here <c>M</c> is a term of type map, <c>V</c> is an expression and <c>K</c>
+ is an expression that evaluates to an existing key in <c>M</c>.
+ </p>
+ <p>
+ If key <c>K</c> does not match any existing keys in map <c>M</c>, an exception
+ of type <c>badarg</c> is triggered at runtime. If a matching key <c>K</c>
+ is present in map <c>M</c>, its associated value is replaced by the new
+ value <c>V</c>, and the evaluated map expression returns a new map.
+ </p>
+ <p>
+ If <c>M</c> is not of type map, an exception of type <c>badmap</c> is thrown.
+ </p>
+ <p>
+ <em>Examples:</em>
+ </p>
+ <code>
+M0 = #{},
+M1 = M0#{a => 0},
+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`.</code>
+ <p>
+ Here <c>M0</c> is any map. It follows that <c>M1 .. M4</c> are maps as well.
+ </p>
+ <p>
+ More <em>Examples:</em>
+ </p>
+<pre>
+1> <input>M = #{1 => a}.</input>
+#{1 => a }
+2> <input>M#{1.0 => b}.</input>
+#{1 => a, 1.0 => b}.
+3> <input>M#{1 := b}.</input>
+#{1 => b}
+4> <input>M#{1.0 := b}.</input>
+** exception error: bad argument
+</pre>
+ <p>
+ 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 that case, the latter value is used.
+ </p>
+ </section>
+
+ <section>
+ <title>Maps in Patterns</title>
+ <p>
+ Matching of key-value associations from maps is done as follows:
+ </p>
+
+ <code>#{ K := V } = M</code>
+ <p>
+ Here <c>M</c> is any map. The key <c>K</c> must be an expression with bound
+ variables or literals. <c>V</c> can be any pattern with either bound or
+ unbound variables.
+ </p>
+ <p>
+ If the variable <c>V</c> is unbound, it becomes bound to the value associated
+ with the key <c>K</c>, which must exist in the map <c>M</c>. If the variable
+ <c>V</c> is bound, it must match the value associated with <c>K</c> in <c>M</c>.
+ </p>
+ <p><em>Example:</em></p>
+<pre>
+1> <input>M = #{"tuple" => {1,2}}.</input>
+#{"tuple" => {1,2}}
+2> <input>#{"tuple" := {1,B}} = M.</input>
+#{"tuple" => {1,2}}
+3> <input>B.</input>
+2.</pre>
+ <p>
+ This binds variable <c>B</c> to integer <c>2</c>.
+ </p>
+ <p>
+ Similarly, multiple values from the map can be matched:
+ </p>
+ <code>#{ K1 := V1, .., Kn := Vn } = M</code>
+ <p>
+ Here keys <c>K1 .. Kn</c> are any expressions with literals or bound variables. If all
+ keys exist in map <c>M</c>, all variables in <c>V1 .. Vn</c> is matched to the
+ associated values of their respective keys.
+ </p>
+ <p>
+ If the matching conditions are not met, the match fails, either with:
+ </p>
+ <list>
+ <item><p>A <c>badmatch</c> exception.</p>
+ <p>This is if it is used in the context of the match operator
+ as in the example.</p>
+ </item>
+ <item><p>Or resulting in the next clause being tested in function heads and
+ case expressions.</p>
+ </item>
+ </list>
+ <p>
+ Matching in maps only allows for <c>:=</c> as delimiters of associations.
+ </p>
+ <p>
+ The order in which keys are declared in matching has no relevance.
+ </p>
+ <p>
+ Duplicate keys are allowed in matching and match each pattern associated
+ to the keys:
+ </p>
+ <code>#{ K := V1, K := V2 } = M</code>
+ <p>
+ Matching an expression against an empty map literal, matches its type but
+ no variables are bound:
+ </p>
+ <code>#{} = Expr</code>
+ <p>
+ This expression matches if the expression <c>Expr</c> is of type map, otherwise
+ it fails with an exception <c>badmatch</c>.
+ </p>
+ <section>
+ <title>Matching Syntax</title>
+ <p>
+ Matching of literals as keys are allowed in function heads:
+ </p>
+ <code>
+%% only start if not_started
+handle_call(start, From, #{ state := not_started } = S) ->
+...
+ {reply, ok, S#{ state := start }};
+
+%% only change if started
+handle_call(change, From, #{ state := start } = S) ->
+...
+ {reply, ok, S#{ state := changed }};</code>
+ </section>
+ </section>
+ <section>
+ <title>Maps in Guards</title>
+ <p>
+ Maps are allowed in guards as long as all subexpressions are valid guard expressions.
+ </p>
+ <p>
+ Two guard BIFs handle maps:
+ </p>
+ <list>
+ <item>
+ <seealso marker="erts:erlang#is_map/1">is_map/1</seealso>
+ in the <c>erlang</c> module
+ </item>
+ <item>
+ <seealso marker="erts:erlang#map_size/1">map_size/1</seealso>
+ in the <c>erlang</c> module
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
<marker id="bit_syntax"></marker>
<title>Bit Syntax Expressions</title>
<code type="none"><![CDATA[<<>>
@@ -805,29 +1083,34 @@ Ei = Value |
Value/TypeSpecifierList |
Value:Size/TypeSpecifierList</pre>
<p>Used in a bit string construction, <c>Value</c> 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.</p>
+ 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 parentheses.</p>
<p>Used in a bit string matching, <c>Value</c> must be a variable,
- or an integer, float or string.</p>
+ or an integer, float, or string.</p>
- <p>Note that, for example, using a string literal as in
+ <p>Notice that, for example, using a string literal as in
<c><![CDATA[<<"abc">>]]></c> is syntactic sugar for
<c><![CDATA[<<$a,$b,$c>>]]></c>.</p>
<p>Used in a bit string construction, <c>Size</c> is an expression
- which should evaluate to an integer.</p>
+ that is to evaluate to an integer.</p>
- <p>Used in a bit string matching, <c>Size</c> must be an integer or a
+ <p>Used in a bit string matching, <c>Size</c> must be an integer, or a
variable bound to an integer.</p>
<p>The value of <c>Size</c> specifies the size of the segment in
units (see below). The default value depends on the type (see
- below). For <c>integer</c> it is 8, for
- <c>float</c> it is 64, for <c>binary</c> and <c>bitstring</c> 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):</p>
+ <list type="bulleted">
+ <item>For <c>integer</c> it is 8.</item>
+ <item>For <c>float</c> it is 64.</item>
+ <item>For <c>binary</c> and <c>bitstring</c> it is
+ the whole binary or bit string.</item>
+ </list>
+ <p>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.</p>
<p>For the <c>utf8</c>, <c>utf16</c>, and <c>utf32</c> types,
@@ -851,7 +1134,7 @@ Ei = Value |
The default is <c>unsigned</c>.</item>
<tag><c>Endianness</c>= <c>big</c> | <c>little</c> | <c>native</c></tag>
- <item>Native-endian means that the endianness will be resolved at load
+ <item>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 <c>integer</c>,
@@ -860,7 +1143,7 @@ Ei = Value |
<tag><c>Unit</c>= <c>unit:IntegerLiteral</c></tag>
<item>The allowed range is 1..256. Defaults to 1 for <c>integer</c>,
- <c>float</c> and <c>bitstring</c>, and to 8 for <c>binary</c>.
+ <c>float</c>, and <c>bitstring</c>, and to 8 for <c>binary</c>.
No unit specifier must be given for the types
<c>utf8</c>, <c>utf16</c>, and <c>utf32</c>.
</item>
@@ -871,8 +1154,8 @@ Ei = Value |
<note><p>When constructing binaries, if the size <c>N</c> 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 <c>N</c> least
- significant bits will be put into the binary.</p></note>
+ bits of the integer are silently discarded and only the <c>N</c> least
+ significant bits are put into the binary.</p></note>
<p>The types <c>utf8</c>, <c>utf16</c>, and <c>utf32</c> specifies
encoding/decoding of the <em>Unicode Transformation Format</em>s UTF-8, UTF-16,
@@ -881,39 +1164,39 @@ Ei = Value |
<p>When constructing a segment of a <c>utf</c> type, <c>Value</c>
must be an integer in the range 0..16#D7FF or
16#E000....16#10FFFF. Construction
- will fail with a <c>badarg</c> exception if <c>Value</c> is
+ fails with a <c>badarg</c> exception if <c>Value</c> is
outside the allowed ranges. The size of the resulting binary
- segment depends on the type and/or <c>Value</c>. For <c>utf8</c>,
- <c>Value</c> will be encoded in 1 through 4 bytes. For
- <c>utf16</c>, <c>Value</c> will be encoded in 2 or 4
- bytes. Finally, for <c>utf32</c>, <c>Value</c> will always be
- encoded in 4 bytes.</p>
+ segment depends on the type or <c>Value</c>, or both:</p>
+ <list type="bulleted">
+ <item>For <c>utf8</c>, <c>Value</c> is encoded in 1-4 bytes.</item>
+ <item>For <c>utf16</c>, <c>Value</c> is encoded in 2 or 4 bytes.</item>
+ <item>For <c>utf32</c>, <c>Value</c> is always be encoded in 4 bytes.</item>
+ </list>
- <p>When constructing, a literal string may be given followed
+ <p>When constructing, a literal string can be given followed
by one of the UTF types, for example: <c><![CDATA[<<"abc"/utf8>>]]></c>
- which is syntatic sugar for
+ which is syntactic sugar for
<c><![CDATA[<<$a/utf8,$b/utf8,$c/utf8>>]]></c>.</p>
- <p>A successful match of a segment of a <c>utf</c> type results
+ <p>A successful match of a segment of a <c>utf</c> 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.</p>
+ The match fails if the returned value falls outside those ranges.</p>
- <p>A segment of type <c>utf8</c> will match 1 to 4 bytes in the binary,
+ <p>A segment of type <c>utf8</c> 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.)</p>
- <p>A segment of type <c>utf16</c> may match 2 or 4 bytes in the binary.
- The match will fail if the binary at the match position does not contain
+ <p>A segment of type <c>utf16</c> 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.)</p>
- <p>A segment of type <c>utf32</c> may match 4 bytes in the binary in the
- same way as an <c>integer</c> segment matching 32 bits.
- The match will fail if the resulting integer is outside the legal ranges
+ <p>A segment of type <c>utf32</c> can match 4 bytes in the binary in the
+ same way as an <c>integer</c> segment matches 32 bits.
+ The match fails if the resulting integer is outside the legal ranges
mentioned above.</p>
- <p>Examples:</p>
+ <p><em>Examples:</em></p>
<pre>
1> <input>Bin1 = &lt;&lt;1,17,42&gt;&gt;.</input>
&lt;&lt;1,17,42&gt;&gt;
@@ -942,11 +1225,13 @@ Ei = Value |
13> <input>&lt;&lt;1024/utf8&gt;&gt;.</input>
&lt;&lt;208,128&gt;&gt;
</pre>
- <p>Note that bit string patterns cannot be nested.</p>
- <p>Note also that "<c><![CDATA[B=<<1>>]]></c>" is interpreted as
+ <p>Notice that bit string patterns cannot be nested.</p>
+ <p>Notice also that "<c><![CDATA[B=<<1>>]]></c>" is interpreted as
"<c><![CDATA[B =<<1>>]]></c>" which is a syntax error. The correct way is
to write a space after '=': "<c><![CDATA[B= <<1>>]]></c>.</p>
- <p>More examples can be found in <em>Programming Examples</em>.</p>
+ <p>More examples are provided in
+ <seealso marker="doc/programming_examples:bit_syntax">
+ Programming Examples</seealso>.</p>
</section>
<section>
@@ -954,22 +1239,23 @@ Ei = Value |
<title>Fun Expressions</title>
<pre>
fun
- (Pattern11,...,Pattern1N) [when GuardSeq1] ->
- Body1;
+ [Name](Pattern11,...,Pattern1N) [when GuardSeq1] ->
+ Body1;
...;
- (PatternK1,...,PatternKN) [when GuardSeqK] ->
- BodyK
+ [Name](PatternK1,...,PatternKN) [when GuardSeqK] ->
+ BodyK
end</pre>
<p>A fun expression begins with the keyword <c>fun</c> and ends
- with the keyword <c>end</c>. Between them should be a function
+ with the keyword <c>end</c>. Between them is to be a function
declaration, similar to a
- <seealso marker="functions#syntax">regular function declaration</seealso>, except that no function name is
- specified.</p>
- <p>Variables in a fun head shadow variables in the
- function clause surrounding the fun expression, and
- variables bound in a fun body are local to the fun body.</p>
+ <seealso marker="functions#syntax">regular function declaration</seealso>,
+ except that the function name is optional and is to be a variable, if
+ any.</p>
+ <p>Variables in a fun head shadow the function name and both shadow
+ variables in the function clause surrounding the fun expression.
+ Variables bound in a fun body are local to the fun body.</p>
<p>The return value of the expression is the resulting fun.</p>
- <p>Examples:</p>
+ <p><em>Examples:</em></p>
<pre>
1> <input>Fun1 = fun (X) -> X+1 end.</input>
#Fun&lt;erl_eval.6.39074546&gt;
@@ -978,7 +1264,11 @@ end</pre>
3> <input>Fun2 = fun (X) when X>=5 -> gt; (X) -> lt end.</input>
#Fun&lt;erl_eval.6.39074546&gt;
4> <input>Fun2(7).</input>
-gt</pre>
+gt
+5> <input>Fun3 = fun Fact(1) -> 1; Fact(X) when X > 1 -> X * Fact(X - 1) end.</input>
+#Fun&lt;erl_eval.6.39074546&gt;
+6> <input>Fun3(4).</input>
+24</pre>
<p>The following fun expressions are also allowed:</p>
<pre>
fun Name/Arity
@@ -988,15 +1278,17 @@ fun Module:Name/Arity</pre>
syntactic sugar for:</p>
<pre>
fun (Arg1,...,ArgN) -> Name(Arg1,...,ArgN) end</pre>
- <p>In <c>Module:Name/Arity</c>, <c>Module</c> and <c>Name</c> are atoms
- and <c>Arity</c> is an integer. Starting from the R15 release,
- <c>Module</c>, <c>Name</c>, and <c>Arity</c> may also be variables.
- A fun defined in this way will refer to the function <c>Name</c>
+ <p>In <c>Module:Name/Arity</c>, <c>Module</c>, and <c>Name</c> are atoms
+ and <c>Arity</c> is an integer. Starting from Erlang/OTP R15,
+ <c>Module</c>, <c>Name</c>, and <c>Arity</c> can also be variables.
+ A fun defined in this way refers to the function <c>Name</c>
with arity <c>Arity</c> in the <em>latest</em> version of module
- <c>Module</c>. A fun defined in this way will not be dependent on
- the code for module in which it is defined.
+ <c>Module</c>. A fun defined in this way is not dependent on
+ the code for the module in which it is defined.
</p>
- <p>More examples can be found in <em>Programming Examples</em>.</p>
+ <p>More examples are provided in
+ <seealso marker="doc/programming_examples:funs">
+ Programming Examples</seealso>.</p>
</section>
<section>
@@ -1006,38 +1298,42 @@ fun (Arg1,...,ArgN) -> Name(Arg1,...,ArgN) end</pre>
catch Expr</code>
<p>Returns the value of <c>Expr</c> unless an exception
occurs during the evaluation. In that case, the exception is
- caught. For exceptions of class <c>error</c>,
- that is run-time errors: <c>{'EXIT',{Reason,Stack}}</c>
- is returned. For exceptions of class <c>exit</c>, that is
- the code called <c>exit(Term)</c>: <c>{'EXIT',Term}</c> is returned.
- For exceptions of class <c>throw</c>, that is
- the code called <c>throw(Term)</c>: <c>Term</c> is returned.</p>
+ caught.</p>
+ <p>For exceptions of class <c>error</c>, that is,
+ run-time errors,
+ <c>{'EXIT',{Reason,Stack}}</c> is returned.</p>
+ <p>For exceptions of class <c>exit</c>, that is,
+ the code called <c>exit(Term)</c>,
+ <c>{'EXIT',Term}</c> is returned.</p>
+ <p>For exceptions of class <c>throw</c>, that is
+ the code called <c>throw(Term)</c>,
+ <c>Term</c> is returned.</p>
<p><c>Reason</c> depends on the type of error that occurred, and
<c>Stack</c> is the stack of recent function calls, see
- <seealso marker="errors#exit_reasons">Errors and Error Handling</seealso>.</p>
- <p>Examples:</p>
- <p></p>
+ <seealso marker="errors#exit_reasons">Exit Reasons</seealso>.</p>
+ <p><em>Examples:</em></p>
<pre>
1> <input>catch 1+2.</input>
3
2> <input>catch 1+a.</input>
{'EXIT',{badarith,[...]}}</pre>
- <p>Note that <c>catch</c> has low precedence and catch
+ <p>Notice that <c>catch</c> has low precedence and catch
subexpressions often needs to be enclosed in a block
- expression or in parenthesis:</p>
+ expression or in parentheses:</p>
<pre>
3> <input>A = catch 1+2.</input>
** 1: syntax error before: 'catch' **
4> <input>A = (catch 1+2).</input>
3</pre>
<p>The BIF <c>throw(Any)</c> can be used for non-local return from
- a function. It must be evaluated within a <c>catch</c>, which will
- return the value <c>Any</c>. Example:</p>
+ a function. It must be evaluated within a <c>catch</c>, which
+ returns the value <c>Any</c>.</p>
+ <p><em>Example:</em></p>
<pre>
5> <input>catch throw(hello).</input>
hello</pre>
<p>If <c>throw/1</c> is not evaluated within a catch, a
- <c>nocatch</c> run-time error will occur.</p>
+ <c>nocatch</c> run-time error occurs.</p>
</section>
<section>
@@ -1053,14 +1349,17 @@ catch
end</code>
<p>This is an enhancement of
<seealso marker="#catch">catch</seealso> that appeared in
- Erlang 5.4/OTP-R10B. It gives the possibility do distinguish
- between different exception classes, and to choose to handle only
- the desired ones, passing the others on to an enclosing
- <c>try</c> or <c>catch</c> or to default error handling.</p>
- <p>Note that although the keyword <c>catch</c> is used in
+ Erlang 5.4/OTP R10B. It gives the possibility to:</p>
+ <list type="bulleted">
+ <item>Distinguish between different exception classes.</item>
+ <item>Choose to handle only the desired ones.</item>
+ <item>Passing the others on to an enclosing
+ <c>try</c> or <c>catch</c>, or to default error handling.</item>
+ </list>
+ <p>Notice that although the keyword <c>catch</c> is used in
the <c>try</c> expression, there is not a <c>catch</c> expression
within the <c>try</c> expression.</p>
- <p>Returns the value of <c>Exprs</c> (a sequence of expressions
+ <p>It returns the value of <c>Exprs</c> (a sequence of expressions
<c>Expr1, ..., ExprN</c>) unless an exception occurs during
the evaluation. In that case the exception is caught and
the patterns <c>ExceptionPattern</c> with the right exception
@@ -1074,7 +1373,7 @@ end</code>
<c>Class</c> with a true guard sequence, the exception is passed
on as if <c>Exprs</c> had not been enclosed in a <c>try</c>
expression.</p>
- <p>If an exception occurs during evaluation of <c>ExceptionBody</c>
+ <p>If an exception occurs during evaluation of <c>ExceptionBody</c>,
it is not caught.</p>
<p>The <c>try</c> expression can have an <c>of</c>
section:
@@ -1097,7 +1396,7 @@ end</code>
the patterns <c>Pattern</c> are sequentially matched against
the result in the same way as for a
<seealso marker="#case">case</seealso> expression, except that if
- the matching fails, a <c>try_clause</c> run-time error will occur.</p>
+ the matching fails, a <c>try_clause</c> run-time error occurs.</p>
<p>An exception occurring during the evaluation of <c>Body</c> is
not caught.</p>
<p>The <c>try</c> expression can also be augmented with an
@@ -1120,7 +1419,7 @@ after
AfterBody
end</code>
<p><c>AfterBody</c> is evaluated after either <c>Body</c> or
- <c>ExceptionBody</c> no matter which one. The evaluated value of
+ <c>ExceptionBody</c>, no matter which one. The evaluated value of
<c>AfterBody</c> is lost; the return value of the <c>try</c>
expression is the same with an <c>after</c> section as without.</p>
<p>Even if an exception occurs during evaluation of <c>Body</c> or
@@ -1129,13 +1428,13 @@ end</code>
evaluated, so the exception from the <c>try</c> expression is
the same with an <c>after</c> section as without.</p>
<p>If an exception occurs during evaluation of <c>AfterBody</c>
- itself it is not caught, so if <c>AfterBody</c> is evaluated after
- an exception in <c>Exprs</c>, <c>Body</c> or <c>ExceptionBody</c>,
+ itself, it is not caught. So if <c>AfterBody</c> is evaluated after
+ an exception in <c>Exprs</c>, <c>Body</c>, or <c>ExceptionBody</c>,
that exception is lost and masked by the exception in
<c>AfterBody</c>.</p>
- <p>The <c>of</c>, <c>catch</c> and <c>after</c> sections are all
+ <p>The <c>of</c>, <c>catch</c>, and <c>after</c> sections are all
optional, as long as there is at least a <c>catch</c> or an
- <c>after</c> section, so the following are valid <c>try</c>
+ <c>after</c> section. So the following are valid <c>try</c>
expressions:</p>
<code type="none">
try Exprs of
@@ -1154,9 +1453,9 @@ after
end
try Exprs after AfterBody end</code>
- <p>Example of using <c>after</c>, this code will close the file
+ <p>Next is an example of using <c>after</c>. This closes the file,
even in the event of exceptions in <c>file:read/2</c> or in
- <c>binary_to_term/1</c>, and exceptions will be the same as
+ <c>binary_to_term/1</c>. The exceptions are the same as
without the <c>try</c>...<c>after</c>...<c>end</c> expression:</p>
<code type="none">
termize_file(Name) ->
@@ -1167,7 +1466,7 @@ termize_file(Name) ->
after
file:close(F)
end.</code>
- <p>Example: Using <c>try</c> to emulate <c>catch Expr</c>.</p>
+ <p>Next is an example of using <c>try</c> to emulate <c>catch Expr</c>:</p>
<code type="none">
try Expr
catch
@@ -1183,7 +1482,7 @@ end</code>
(Expr)</pre>
<p>Parenthesized expressions are useful to override
<seealso marker="#prec">operator precedences</seealso>,
- for example in arithmetic expressions:</p>
+ for example, in arithmetic expressions:</p>
<pre>
1> <input>1 + 2 * 3.</input>
7
@@ -1207,7 +1506,7 @@ end</pre>
<section>
<marker id="lcs"></marker>
<title>List Comprehensions</title>
- <p>List comprehensions are a feature of many modern functional
+ <p>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.</p>
<p>List comprehensions are analogous to set comprehensions in
@@ -1217,32 +1516,34 @@ end</pre>
<p>List comprehensions are written with the following syntax:</p>
<pre>
[Expr || Qualifier1,...,QualifierN]</pre>
- <p><c>Expr</c> is an arbitrary expression, and each
+ <p>Here, <c>Expr</c> is an arbitrary expression, and each
<c>Qualifier</c> is either a generator or a filter.</p>
<list type="bulleted">
<item>A <em>generator</em> is written as: <br></br>
&nbsp;&nbsp;<c><![CDATA[Pattern <- ListExpr]]></c>. <br></br>
-<c>ListExpr</c> must be an expression which evaluates to a
+<c>ListExpr</c> must be an expression, which evaluates to a
list of terms.</item>
<item>A <em>bit string generator</em> is written as: <br></br>
&nbsp;&nbsp;<c><![CDATA[BitstringPattern <= BitStringExpr]]></c>. <br></br>
-<c>BitStringExpr</c> must be an expression which evaluates to a
+<c>BitStringExpr</c> must be an expression, which evaluates to a
bitstring.</item>
- <item>A <em>filter</em> is an expression which evaluates to
+ <item>A <em>filter</em> is an expression, which evaluates to
<c>true</c> or <c>false</c>.</item>
</list>
- <p>The variables in the generator patterns shadow variables in the function
- clause surrounding the list comprehensions.</p> <p>A list comprehension
+ <p>The variables in the generator patterns, shadow variables in the function
+ clause, surrounding the list comprehensions.</p> <p>A list comprehension
returns a list, where the elements are the result of evaluating <c>Expr</c>
for each combination of generator list elements and bit string generator
- elements for which all filters are true.</p> <p></p> <p>Example:</p>
+ elements, for which all filters are true.</p>
+ <p><em>Example:</em></p>
<pre>
1> <input>[X*2 || X &lt;- [1,2,3]].</input>
[2,4,6]</pre>
- <p>More examples can be found in <em>Programming Examples</em>.</p>
-
+ <p>More examples are provoded in
+ <seealso marker="doc/programming_examples:list_comprehensions">
+ Programming Examples.</seealso></p>
</section>
@@ -1255,35 +1556,38 @@ end</pre>
<p>Bit string comprehensions are written with
the following syntax:</p>
<pre>
-&lt;&lt; BitString || Qualifier1,...,QualifierN &gt;&gt;</pre>
- <p><c>BitString</c> is a bit string expression, and each
- <c>Qualifier</c> is either a generator, a bit string generator or a filter.</p>
+&lt;&lt; BitStringExpr || Qualifier1,...,QualifierN &gt;&gt;</pre>
+ <p><c>BitStringExpr</c> is an expression that evalutes to a bit
+ string. If <c>BitStringExpr</c> is a function call, it must be
+ enclosed in parentheses. Each <c>Qualifier</c> is either a
+ generator, a bit string generator or a filter.</p>
<list type="bulleted">
<item>A <em>generator</em> is written as: <br></br>
&nbsp;&nbsp;<c><![CDATA[Pattern <- ListExpr]]></c>. <br></br>
- <c>ListExpr</c> must be an expression which evaluates to a
+ <c>ListExpr</c> must be an expression that evaluates to a
list of terms.</item>
<item>A <em>bit string generator</em> is written as: <br></br>
&nbsp;&nbsp;<c><![CDATA[BitstringPattern <= BitStringExpr]]></c>. <br></br>
-<c>BitStringExpr</c> must be an expression which evaluates to a
+<c>BitStringExpr</c> must be an expression that evaluates to a
bitstring.</item>
- <item>A <em>filter</em> is an expression which evaluates to
+ <item>A <em>filter</em> is an expression that evaluates to
<c>true</c> or <c>false</c>.</item>
</list>
- <p>The variables in the generator patterns shadow variables in
- the function clause surrounding the bit string comprehensions.</p>
+ <p>The variables in the generator patterns, shadow variables in
+ the function clause, surrounding the bit string comprehensions.</p>
<p>A bit string comprehension returns a bit string, which is
created by concatenating the results of evaluating <c>BitString</c>
- for each combination of bit string generator elements for which all
+ for each combination of bit string generator elements, for which all
filters are true.</p>
- <p></p>
- <p>Example:</p>
+ <p><em>Example:</em></p>
<pre>
-1> <input>&lt;&lt; &lt;&lt; (X*2) &gt;&gt; ||
+1> <input>&lt;&lt; &lt;&lt; (X*2) &gt;&gt; ||
&lt;&lt;X&gt;&gt; &lt;= &lt;&lt; 1,2,3 &gt;&gt; &gt;&gt;.</input>
&lt;&lt;2,4,6&gt;&gt;</pre>
- <p>More examples can be found in <em>Programming Examples</em>.</p>
+ <p>More examples are provided in
+ <seealso marker="doc/programming_examples:bit_syntax">
+ Programming Examples.</seealso></p>
</section>
<section>
@@ -1292,27 +1596,27 @@ end</pre>
<p>A <em>guard sequence</em> 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.)<br></br>
-<c>Guard1;...;GuardK</c></p>
+ the guards is true. (The remaining guards, if any, are not
+ evaluated.)</p>
+ <p><c>Guard1;...;GuardK</c></p>
<p>A <em>guard</em> is a sequence of guard expressions, separated
by comma (,). The guard is true if all guard expressions
- evaluate to <c>true</c>.<br></br>
-<c>GuardExpr1,...,GuardExprN</c></p>
+ evaluate to <c>true</c>.</p>
+ <p><c>GuardExpr1,...,GuardExprN</c></p>
<p>The set of valid <em>guard expressions</em> (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:</p>
+ of side effects. Valid guard expressions are the following:</p>
<list type="bulleted">
- <item>the atom <c>true</c>,</item>
- <item>other constants (terms and bound variables), all regarded
- as false,</item>
- <item>calls to the BIFs specified below,</item>
- <item>term comparisons,</item>
- <item>arithmetic expressions,</item>
- <item>boolean expressions, and</item>
- <item>short-circuit expressions (<c>andalso</c>/<c>orelse</c>).</item>
+ <item>The atom <c>true</c></item>
+ <item>Other constants (terms and bound variables), all regarded
+ as false</item>
+ <item>Calls to the BIFs specified in table <c>Type Test BIFs</c></item>
+ <item>Term comparisons</item>
+ <item>Arithmetic expressions</item>
+ <item>Boolean expressions</item>
+ <item>Short-circuit expressions (<c>andalso</c>/<c>orelse</c>)</item>
</list>
<table>
<row>
@@ -1343,6 +1647,9 @@ end</pre>
<cell align="left" valign="middle"><c>is_list/1</c></cell>
</row>
<row>
+ <cell align="left" valign="middle"><c>is_map/1</c></cell>
+ </row>
+ <row>
<cell align="left" valign="middle"><c>is_number/1</c></cell>
</row>
<row>
@@ -1363,13 +1670,13 @@ end</pre>
<row>
<cell align="left" valign="middle"><c>is_tuple/1</c></cell>
</row>
- <tcaption>Type Test BIFs.</tcaption>
+ <tcaption>Type Test BIFs</tcaption>
</table>
- <p>Note that most type test BIFs have older equivalents, without
+ <p>Notice that most type test BIFs have older equivalents, without
the <c>is_</c> prefix. These old BIFs are retained for backwards
- compatibility only and should not be used in new code. They are
+ compatibility only and are not to be used in new code. They are
also only allowed at top level. For example, they are not allowed
- in boolean expressions in guards.</p>
+ in Boolean expressions in guards.</p>
<table>
<row>
<cell align="left" valign="middle"><c>abs(Number)</c></cell>
@@ -1393,6 +1700,9 @@ end</pre>
<cell align="left" valign="middle"><c>length(List)</c></cell>
</row>
<row>
+ <cell align="left" valign="middle"><c>map_size(Map)</c></cell>
+ </row>
+ <row>
<cell align="left" valign="middle"><c>node()</c></cell>
</row>
<row>
@@ -1416,14 +1726,14 @@ end</pre>
<row>
<cell align="left" valign="middle"><c>tuple_size(Tuple)</c></cell>
</row>
- <tcaption>Other BIFs Allowed in Guard Expressions.</tcaption>
+ <tcaption>Other BIFs Allowed in Guard Expressions</tcaption>
</table>
- <p>If an arithmetic expression, a boolean expression, a
+ <p>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.</p>
+ the guard following the next semicolon) is evaluated.</p>
</section>
@@ -1476,12 +1786,13 @@ end</pre>
<cell align="left" valign="middle">catch</cell>
<cell align="left" valign="middle">&nbsp;</cell>
</row>
- <tcaption>Operator Precedence.</tcaption>
+ <tcaption>Operator Precedence</tcaption>
</table>
<p>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.</p>
+ <p><em>Example:</em></p>
+ <p>The left associative arithmetic operators are evaluated left to
right:</p>
<pre>
<input>6 + 5 * 4 - 3 / 2</input> evaluates to