From f98300fbe9bb29eb3eb2182b12094974a6dc195b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= In Erlang a Bin is used for constructing binaries and matching
+ In Erlang, a Bin is used for constructing binaries and matching
binary patterns. A Bin is written with the following syntax: A Bin is a low-level sequence of bits or bytes. The purpose of a Bin is
- to be able to, from a high level, construct a binary, A Bin is a low-level sequence of bits or bytes.
+ The purpose of a Bin is to enable construction of binaries: in which case all elements must be bound, or to match a binary, All elements must be bound. Or match a binary: where Here, In R12B, a Bin need not consist of a whole number of bytes. Since Erlang R12B, a Bin does not need to consist of a whole number of bytes. A bitstring is a sequence of zero or more bits, where
- the number of bits doesn't need to be divisible by 8. If the number
+ the number of bits does not need to be divisible by 8. If the number
of bits is divisible by 8, the bitstring is also a binary. Each element specifies a certain segment of the bitstring.
A segment is a set of contiguous bits of the binary (not
necessarily on a byte boundary). The first element specifies
the initial segment, the second element specifies the following
- segment etc. The following examples illustrate how binaries are constructed
+ segment, and so on. The following examples illustrate how binaries are constructed,
or matched, and how elements and tails are specified. Example 1: A binary can be constructed from a set of
+ Example 1: A binary can be constructed from a set of
constants or a string literal: yields binaries of size 3; Example 2: Similarly, a binary can be constructed
+ This gives two binaries of size 3, with the following evaluations: Example 2:Similarly, a binary can be constructed
from a set of bound variables: yields a binary of size 4, and This gives a binary of size 4.
+ Here, a size expression is used for the variable Example 3: A Bin can also be used for matching: if
+ Example 3: A Bin can also be used for matching.
>]]>
- >]]>
- > = Bin ]]>
- >,
Bin12 = <<"abc">>]]>
-
+
+ >]]>
-
> = Bin2]]>
- yields
This gives
Example 4: The following is a more elaborate example
- of matching, where
> = RestDgram,
...
end.]]>
- Here the segment corresponding to the
Here, the segment corresponding to the
An IP datagram header is of variable length, and its length -
- measured in the number of 32-bit words - is given in
- the segment corresponding to
An IP datagram header is of variable length. This length is
+ measured in the number of 32-bit words and is given in
+ the segment corresponding to
The tail variables
If the first 4-bits segment of
The match of
Note that "
Notice that "
Each segment has the following general syntax:
Both the
Default values will be used for missing specifications. - The default values are described in the section +
The
Default values are used when specifications are missing.
+ The default values are described in
Used in binary construction, the
The
The
Example:
+Example:
X:4/little-signed-integer-unit:8
This element has a total size of 4*8 = 32 bits, and it contains
@@ -184,13 +192,14 @@ X:4/little-signed-integer-unit:8
The default The default unit depends on the the type. For This section describes the rules for constructing binaries using
the bit syntax. Unlike when constructing lists or tuples,
the construction of a binary can fail with a There can be zero or more segments in a binary to be
- constructed. The expression ' Each segment in a binary can consist of zero or more bits.
There are no alignment rules for individual segments of type
Example: The variable >]]>
On the other hand, the variable
The
For clarity, it is recommended not to change the unit
- size for binaries, but to use
For clarity, it is recommended not to change the unit
+ size for binaries. Instead, use
The following example
+The following example successfully constructs a bitstring of 7 bits, + provided that all of X and Y are integers:
>]]>
- will successfully construct a bitstring of 7 bits. - (Provided that all of X and Y are integers.)
-As noted earlier, segments have the following general syntax:
+As mentioned earlier, segments have the following general syntax:
When constructing binaries,
>]]>
- This expression must be rewritten to
+This expression must be rewritten into the following, + to be accepted by the compiler:
>]]>
- in order to be accepted by the compiler.
As syntactic sugar, an literal string may be written instead - of a element.
+A literal string can be written instead of an element:
>]]>
- which is syntactic sugar for
+This is syntactic sugar for the following:
>]]>
This section describes the rules for matching binaries using
+
This section describes the rules for matching binaries, using the bit syntax.
There can be zero or more segments in a binary pattern. - A binary pattern can occur in every place patterns are allowed, - also inside other patterns. Binary patterns cannot be nested.
-The pattern '
Each segment in a binary can consist of zero or more bits.
-A segment of type
A segment of type
As noted earlier, segments have the following general syntax:
+ A binary pattern can occur wherever patterns are allowed, + including inside other patterns. Binary patterns cannot be nested. + The patternEach segment in a binary can consist of zero or more bits.
+ A segment of type
As mentioned earlier, segments have the following general syntax:
When matching
When matching
>) ->
{X,T}.]]>
The two occurrences of
The correct way to write this example is like this:
+The correct way to write this example is as follows:
<> = Bin,
@@ -303,14 +312,14 @@ foo(<>) ->]]>
without size:
>) ->]]>
- There is no restriction on the number of bits in the tail.
+There are no restrictions on the number of bits in the tail.
In R12B, the following function for creating a binary out of - a list of triples of integers is now efficient:
+Since Erlang R12B, the following function for creating a binary out of + a list of triples of integers is efficient:
triples_to_bin(T, <<>>).
@@ -321,7 +330,8 @@ triples_to_bin([], Acc) ->
Acc.]]>
In previous releases, this function was highly inefficient, because
the binary constructed so far (
If we want to double every element in a list, we could write a
- function named
The following function,
double([H|T]) -> [2*H|double(T)];
double([]) -> [].
- This function obviously doubles the argument entered as input - as follows:
+Hence, the argument entered as input is doubled as follows:
> double([1,2,3,4]). [2,4,6,8]-
We now add the function
The following function,
add_one([H|T]) -> [H+1|add_one(T)];
add_one([]) -> [].
- These functions,
The functions
We can now express the functions
The functions
double(L) -> map(fun(X) -> 2*X end, L).
add_one(L) -> map(fun(X) -> 1 + X end, L).
- The process of abstracting out the common features of a number - of different programs is called procedural abstraction. - Procedural abstraction can be used in order to write several - different functions which have a similar structure, but differ - only in some minor detail. This is done as follows:
+ of different programs is called procedural abstraction. + Procedural abstraction can be used to write several + different functions that have a similar structure, but differ + in some minor detail. This is done as follows:This example illustrates procedural abstraction. Initially, we - show the following two examples written as conventional - functions:
-This section illustrates procedural abstraction. Initially, + the following two examples are written as conventional + functions.
+This function prints all elements of a list onto a stream:
print_list(Stream, [H|T]) ->
io:format(Stream, "~p~n", [H]),
print_list(Stream, T);
print_list(Stream, []) ->
true.
+ This function broadcasts a message to a list of processes:
broadcast(Msg, [Pid|Pids]) ->
Pid ! Msg,
broadcast(Msg, Pids);
broadcast(_, []) ->
true.
- Both these functions have a very similar structure. They both - iterate over a list doing something to each element in the list. - The "something" has to be carried round as an extra argument to - the function which does this.
+These two functions have a similar structure. They both + iterate over a list and do something to each element in the list. + The "something" is passed on as an extra argument to + the function that does this.
The function
Using
Using the function
foreach(fun(H) -> io:format(S, "~p~n",[H]) end, L)
- Using the function
foreach(fun(Pid) -> Pid ! M end, L)
Funs are written with the syntax:
+Funs are written with the following syntax:
F = fun (Arg1, Arg2, ... ArgN) ->
...
end
This creates an anonymous function of
If we have already written a function in the same module and - wish to pass this function as an argument, we can use - the following syntax:
+Another function,
F = fun FunctionName/Arity
- With this form of function reference, the function which is +
With this form of function reference, the function that is referred to does not need to be exported from the module.
-We can also refer to a function defined in a different module +
It is also possible to refer to a function defined in a different module, with the following syntax:
F = {Module, FunctionName}
In this case, the function must be exported from the module in question.
-The follow program illustrates the different ways of creating +
The following program illustrates the different ways of creating funs:
We can evaluate the fun
The fun
F(Arg1, Arg2, ..., Argn)
To check whether a term is a fun, use the test
-
Example:
f(F, Args) when is_function(F) ->
apply(F, Args);
f(N, _) when is_integer(N) ->
N.
- Funs are a distinct type. The BIFs erlang:fun_info/1,2 can +
Funs are a distinct type. The BIFs
In OTP R5 and earlier releases, funs were represented using
@@ -161,15 +157,15 @@ f(N, _) when is_integer(N) ->
The scope rules for variables which occur in funs are as
+ The scope rules for variables that occur in funs are as
follows: The following examples illustrate these rules: In the above example, the variable Here, the variable Since any variable which occurs in the head of a fun is
- considered a new variable it would be equally valid to write: As any variable that occurs in the head of a fun is
+ considered a new variable, it is equally valid to write
+ as follows: In this example, Here, This reminds us that the variable This indicates that the variable The rules for importing variables into a fun has the consequence
- that certain pattern matching operations have to be moved into
+ that certain pattern matching operations must be moved into
guard expressions and cannot be written in the head of the fun.
- For example, we might write the following code if we intend
+ For example, you might write the following code if you intend
the first clause of instead of instead of writng the following code: The following examples show a dialogue with the Erlang shell.
All the higher order functions discussed are exported from
the module It returns the list obtained by applying the function
to every argument in the list. When a new fun is defined in the shell, the value of the fun
+ is printed as When a new fun is defined in the shell, the value of the Fun
- is printed as We define a predicate
-
@@ -177,12 +173,13 @@ print_list(File, List) ->
{ok, Stream} = file:open(File, write),
foreach(fun(X) -> io:format(Stream,"~p~n",[X]) end, List),
file:close(Stream).
-
print_list(File, List) ->
{ok, Stream} = file:open(File, write),
@@ -190,21 +187,21 @@ print_list(File, List) ->
io:format(Stream,"~p~n",[File])
end, List),
file:close(Stream).
-
./FileName.erl:Line: Warning: variable 'File'
shadowed in 'lambda head'
-
@@ -216,7 +213,7 @@ f(...) ->
...
end, ...)
...
-
f(...) ->
Y = ...
@@ -229,35 +226,37 @@ f(...) ->
> Double = fun(X) -> 2 * X end.
#Fun<erl_eval.6.72228031>
> lists:map(Double, [1,2,3,4,5]).
[2,4,6,8,10]
-
A predicate is a function that returns
A predicate
> Big = fun(X) -> if X > 10 -> true; true -> false end end. #Fun<erl_eval.6.72228031> @@ -269,9 +268,10 @@ true
It is
> lists:all(Big, [1,2,3,4,12,6]). false @@ -281,11 +281,12 @@ true
The function is applied to each argument in the list.
+
> lists:foreach(fun(X) -> io:format("~w~n",[X]) end, [1,2,3,4]).
1
@@ -297,15 +298,16 @@ ok
The function is called with two arguments. The first argument is the successive elements in - the list, the second argument is the accumulator. The function - must return a new accumulator which is used the next time + the list. The second argument is the accumulator. The function + must return a new accumulator, which is used the next time the function is called.
-If we have a list of lists
If you have a list of lists
> L = ["I","like","Erlang"].
@@ -325,11 +327,11 @@ end
mapfoldl
+ mapfoldl simultaneously maps and folds over a list:
- mapfoldl simultaneously maps and folds over a list.
- The following example shows how to change all letters in
- L to upper case and count them.
- First upcase:
+ The following example shows how to change all letters in
+ L to upper case and then count them.
+ First the change to upper case:
> Upcase = fun(X) when $a =< X, X =< $z -> X + $A - $a;
(X) -> X
@@ -344,7 +346,7 @@ end
"ERLANG"
> lists:map(Upcase_word, L).
["I","LIKE","ERLANG"]
- Now we can do the fold and the map at the same time:
+ Now, the fold and the map can be done at the same time:
> lists:mapfoldl(fun(Word, Sum) ->
{Upcase_word(Word), Sum + length(Word)}
@@ -354,23 +356,24 @@ end
filter
-
filter takes a predicate of one argument and a list
- and returns all element in the list which satisfy
- the predicate.
+ and returns all elements in the list that satisfy
+ the predicate:
+
> lists:filter(Big, [500,12,2,45,6,7]).
[500,12,45]
- When we combine maps and filters we can write very succinct
- code. For example, suppose we want to define a set difference
- function. We want to define diff(L1, L2) to be
- the difference between the lists L1 and L2 .
- This is the list of all elements in L1 which are not contained
- in L2. This code can be written as follows:
+ Combining maps and filters enables writing of very succinct
+ code. For example, to define a set difference
+ function diff(L1, L2) to be
+ the difference between the lists L1 and L2 ,
+ the code can be written as follows:
diff(L1, L2) ->
filter(fun(X) -> not member(X, L2) end, L1).
- The AND intersection of the list L1 and L2 is
+
This gives the list of all elements in L1 that are not contained
+ in L2.
+ The AND intersection of the list L1 and L2 is
also easily defined:
intersection(L1,L2) -> filter(fun(X) -> member(X,L1) end, L2).
@@ -378,9 +381,9 @@ intersection(L1,L2) -> filter(fun(X) -> member(X,L1) end, L2).
takewhile
-
takewhile(P, L) takes elements X from a list
- L as long as the predicate P(X) is true.
+ L as long as the predicate P(X) is true:
+
> lists:takewhile(Big, [200,500,45,5,3,45,6]).
[200,500,45]
@@ -388,8 +391,8 @@ intersection(L1,L2) -> filter(fun(X) -> member(X,L1) end, L2).
dropwhile
+ dropwhile is the complement of takewhile :
- dropwhile is the complement of takewhile .
> lists:dropwhile(Big, [200,500,45,5,3,45,6]).
[5,3,45,6]
@@ -397,10 +400,10 @@ intersection(L1,L2) -> filter(fun(X) -> member(X,L1) end, L2).
splitwith
-
splitwith(P, L) splits the list L into the two
- sub-lists {L1, L2} , where L = takewhile(P, L)
- and L2 = dropwhile(P, L) .
+ sublists {L1, L2} , where L = takewhile(P, L)
+ and L2 = dropwhile(P, L) :
+
> lists:splitwith(Big, [200,500,45,5,3,45,6]).
{[200,500,45],[5,3,45,6]}
@@ -408,17 +411,17 @@ intersection(L1,L2) -> filter(fun(X) -> member(X,L1) end, L2).
- Funs Which Return Funs
- So far, this section has only described functions which take
- funs as arguments. It is also possible to write more powerful
- functions which themselves return funs. The following examples
- illustrate these type of functions.
+ Funs Returning Funs
+ So far, only functions that take
+ funs as arguments have been described. More powerful
+ functions, that themselves return funs, can also be written. The following
+ examples illustrate these type of functions.
Simple Higher Order Functions
- Adder(X) is a function which, given X , returns
+
Adder(X) is a function that given X , returns
a new function G such that G(K) returns
- K + X .
+ K + X :
> Adder = fun(X) -> fun(Y) -> X + Y end end.
#Fun<erl_eval.6.72228031>
@@ -438,7 +441,7 @@ ints_from(N) ->
fun() ->
[N|ints_from(N+1)]
end.
- Then we can proceed as follows:
+ Then proceed as follows:
> XX = lazy:ints_from(1).
#Fun<lazy.0.29874839>
@@ -450,7 +453,7 @@ ints_from(N) ->
#Fun<lazy.0.29874839>
> hd(Y()).
2
- etc. - this is an example of "lazy embedding".
+ And so on. This is an example of "lazy embedding".
@@ -459,17 +462,21 @@ ints_from(N) ->
Parser(Toks) -> {ok, Tree, Toks1} | fail
Toks is the list of tokens to be parsed. A successful
- parse returns {ok, Tree, Toks1} , where Tree is a
- parse tree and Toks1 is a tail of Tree which
- contains symbols encountered after the structure which was
- correctly parsed. Otherwise fail is returned.
- The example which follows illustrates a simple, functional
- parser which parses the grammar:
+ parse returns {ok, Tree, Toks1} .
+
+ Tree is a parse tree.
+ Toks1 is a tail of Tree that
+ contains symbols encountered after the structure that was
+ correctly parsed.
+
+ An unsuccessful parse returns fail .
+ The following example illustrates a simple, functional
+ parser that parses the grammar:
(a | b) & (c | d)
The following code defines a function pconst(X) in
- the module funparse , which returns a fun which parses a
- list of tokens.
+ the module funparse , which returns a fun that parses a
+ list of tokens:
This function can be used as follows:
@@ -479,17 +486,18 @@ Parser(Toks) -> {ok, Tree, Toks1} | fail
{ok,{const,a},[b,c]}
> P1([x,y,z]).
fail
- Next, we define the two higher order functions pand
- and por which combine primitive parsers to produce more
- complex parsers. Firstly pand :
+ Next, the two higher order functions pand
+ and por are defined. They combine primitive parsers to produce more
+ complex parsers.
+ First pand :
Given a parser P1 for grammar G1 , and a parser
P2 for grammar G2 , pand(P1, P2) returns a
- parser for the grammar which consists of sequences of tokens
- which satisfy G1 followed by sequences of tokens which
+ parser for the grammar, which consists of sequences of tokens
+ that satisfy G1 , followed by sequences of tokens that
satisfy G2 .
por(P1, P2) returns a parser for the language
- described by the grammar G1 or G2 .
+ described by the grammar G1 or G2 :
The original problem was to parse the grammar
. The following code addresses this
@@ -497,7 +505,7 @@ fail
The following code adds a parser interface to the grammar:
We can test this parser as follows:
+The parser can be tested as follows:
> funparse:parse([a,c]).
{ok,{'and',{'or',1,{const,a}},{'or',1,{const,c}}}}
diff --git a/system/doc/programming_examples/list_comprehensions.xml b/system/doc/programming_examples/list_comprehensions.xml
index d6c8a66e13..5b33b14dea 100644
--- a/system/doc/programming_examples/list_comprehensions.xml
+++ b/system/doc/programming_examples/list_comprehensions.xml
@@ -31,18 +31,15 @@
Simple Examples
- We start with a simple example:
+ This section starts with a simple example, showing a generator and a filter:
> [X || X <- [1,2,a,3,4,b,5,6], X > 3].
[a,4,b,5,6]
- This should be read as follows:
-
- The list of X such that X is taken from the list
+
This is read as follows: The list of X such that X is taken from the list
[1,2,a,...] and X is greater than 3.
-
The notation is a generator and
the expression X > 3 is a filter.
- An additional filter can be added in order to restrict
+
An additional filter, integer(X) , can be added to restrict
the result to integers:
> [X || X <- [1,2,a,3,4,b,5,6], integer(X), X > 3].
@@ -56,7 +53,7 @@
Quick Sort
- The well known quick sort routine can be written as follows:
+ The well-known quick sort routine can be written as follows:
sort([ X || X <- T, X < Pivot]) ++
@@ -64,15 +61,20 @@ sort([Pivot|T]) ->
sort([ X || X <- T, X >= Pivot]);
sort([]) -> [].]]>
The expression is the list of
- all elements in T , which are less than Pivot .
+ all elements in T that are less than Pivot .
= Pivot]]]> is the list of all elements in
- T , which are greater or equal to Pivot .
- To sort a list, we isolate the first element in the list and
- split the list into two sub-lists. The first sub-list contains
- all elements which are smaller than the first element in
- the list, the second contains all elements which are greater
- than or equal to the first element in the list. We then sort
- the sub-lists and combine the results.
+ T that are greater than or equal to Pivot .
+ A list sorted as follows:
+
+ - The first element in the list is isolated
+ and the list is split into two sublists.
+ - The first sublist contains
+ all elements that are smaller than the first element in
+ the list.
+ - The second sublist contains all elements that are greater
+ than, or equal to, the first element in the list.
+ - Then the sublists are sorted and the results are combined.
+
@@ -82,10 +84,10 @@ sort([]) -> [].]]>
[[]];
perms(L) -> [[H|T] || H <- L, T <- perms(L--[H])].]]>
- We take take H from L in all possible ways.
+
This takes H from L in all possible ways.
The result is the set of all lists [H|T] , where T
- is the set of all possible permutations of L with
- H removed.
+ is the set of all possible permutations of L , with
+ H removed:
> perms([b,u,g]).
[[b,u,g],[b,g,u],[u,b,g],[u,g,b],[g,b,u],[g,u,b]]
@@ -97,7 +99,7 @@ perms(L) -> [[H|T] || H <- L, T <- perms(L--[H])].]]>
that A**2 + B**2 = C**2 .
The function pyth(N) generates a list of all integers
{A,B,C} such that A**2 + B**2 = C**2 and where
- the sum of the sides is equal to or less than N .
+ the sum of the sides is equal to, or less than, N :
[ {A,B,C} ||
@@ -140,7 +142,7 @@ pyth1(N) ->
- Simplifications with List Comprehensions
+ Simplifications With List Comprehensions
As an example, list comprehensions can be used to simplify some
of the functions in lists.erl :
[X || X <- L, Pred(X)].]]>
Variable Bindings in List Comprehensions
- The scope rules for variables which occur in list
+
The scope rules for variables that occur in list
comprehensions are as follows:
- - all variables which occur in a generator pattern are
- assumed to be "fresh" variables
- - any variables which are defined before the list
- comprehension and which are used in filters have the values
- they had before the list comprehension
- - no variables may be exported from a list comprehension.
+ - All variables that occur in a generator pattern are
+ assumed to be "fresh" variables.
+ - Any variables that are defined before the list
+ comprehension, and that are used in filters, have the values
+ they had before the list comprehension.
+ - Variables cannot be exported from a list comprehension.
- As an example of these rules, suppose we want to write
+
As an example of these rules, suppose you want to write
the function select , which selects certain elements from
- a list of tuples. We might write
+ a list of tuples. Suppose you write
[Y || {X, Y} <- L].]]> with the intention
- of extracting all tuples from L where the first item is
+ of extracting all tuples from L , where the first item is
X .
- Compiling this yields the following diagnostic:
+ Compiling this gives the following diagnostic:
./FileName.erl:Line: Warning: variable 'X' shadowed in generate
- This diagnostic warns us that the variable X in
- the pattern is not the same variable as the variable X
- which occurs in the function head.
- Evaluating select yields the following result:
+ This diagnostic warns that the variable X in
+ the pattern is not the same as the variable X
+ that occurs in the function head.
+ Evaluating select gives the following result:
> select(b,[{a,1},{b,2},{c,3},{b,7}]).
[1,2,3,7]
- This result is not what we wanted. To achieve the desired
- effect we must write select as follows:
+ This is not the wanted result. To achieve the desired
+ effect, select must be written as follows:
[Y || {X1, Y} <- L, X == X1].]]>
The generator now contains unbound variables and the test has
- been moved into the filter. This now works as expected:
+ been moved into the filter.
+ This now works as expected:
> select(b,[{a,1},{b,2},{c,3},{b,7}]).
[2,7]
- One consequence of the rules for importing variables into a
+
A consequence of the rules for importing variables into a
list comprehensions is that certain pattern matching operations
- have to be moved into the filters and cannot be written directly
- in the generators. To illustrate this, do not write as follows:
+ must be moved into the filters and cannot be written directly
+ in the generators.
+ To illustrate this, do not write as follows:
Y = ...
diff --git a/system/doc/programming_examples/part.xml b/system/doc/programming_examples/part.xml
index 0bec9b4cf5..9329717ce4 100644
--- a/system/doc/programming_examples/part.xml
+++ b/system/doc/programming_examples/part.xml
@@ -28,8 +28,9 @@
- This chapter contains examples on using records, funs, list
- comprehensions and the bit syntax.
+
+ This section contains examples on using records, funs, list
+ comprehensions, and the bit syntax.
diff --git a/system/doc/programming_examples/records.xml b/system/doc/programming_examples/records.xml
index 58cf136a0b..ffcc05e758 100644
--- a/system/doc/programming_examples/records.xml
+++ b/system/doc/programming_examples/records.xml
@@ -30,37 +30,39 @@
- Records vs Tuples
- The main advantage of using records instead of tuples is that
+
Records and Tuples
+ The main advantage of using records rather than tuples is that
fields in a record are accessed by name, whereas fields in a
tuple are accessed by position. To illustrate these differences,
- suppose that we want to represent a person with the tuple
+ suppose that you want to represent a person with the tuple
{Name, Address, Phone} .
- We must remember that the Name field is the first
- element of the tuple, the Address field is the second
- element, and so on, in order to write functions which manipulate
- this data. For example, to extract data from a variable P
- which contains such a tuple we might write the following code
- and then use pattern matching to extract the relevant fields.
+ To write functions that manipulate this data, remember the following:
+
+ - The
Name field is the first element of the tuple.
+ - The
Address field is the second element.
+ - The
Phone field is the third element.
+
+ For example, to extract data from a variable P
+ that contains such a tuple, you can write the following code
+ and then use pattern matching to extract the relevant fields:
Name = element(1, P),
Address = element(2, P),
...
- Code like this is difficult to read and understand and errors
- occur if we get the numbering of the elements in the tuple wrong.
- If we change the data representation by re-ordering the fields,
- or by adding or removing a field, then all references to
- the person tuple, wherever they occur, must be checked and
- possibly modified.
- Records allow us to refer to the fields by name and not
- position. We use a record instead of a tuple to store the data.
- If we write a record definition of the type shown below, we can
- then refer to the fields of the record by name.
+ Such code is difficult to read and understand, and errors
+ occur if the numbering of the elements in the tuple is wrong.
+ If the data representation of the fields is changed, by re-ordering,
+ adding, or removing fields, all references to
+ the person tuple must be checked and possibly modified.
+ Records allow references to the fields by name, instead of by
+ position. In the following example, a record instead of a tuple
+ is used to store the data:
-record(person, {name, phone, address}).
- For example, if P is now a variable whose value is a
- person record, we can code as follows in order to access
- the name and address fields of the records.
+ This enables references to the fields of the record by name.
+ For example, if P is a variable whose value is a
+ person record, the following code access
+ the name and address fields of the records:
Name = P#person.name,
Address = P#person.address,
@@ -72,24 +74,25 @@ Address = P#person.address,
Defining a Record
- This definition of a person will be used in many of
- the examples which follow. It contains three fields, name ,
- phone and address . The default values for
+
This following definition of a person is used in several
+ examples in this section. Three fields are included, name ,
+ phone , and address . The default values for
name and phone is "" and [], respectively.
The default value for address is the atom
undefined , since no default value is supplied for this
field:
-record(person, {name = "", phone = [], address}).
- We have to define the record in the shell in order to be able
- use the record syntax in the examples:
+ The record must be defined in the shell to enable
+ use of the record syntax in the examples:
> rd(person, {name = "", phone = [], address}).
person
- This is due to the fact that record definitions are available
- at compile time only, not at runtime. See shell(3) for
- details on records in the shell.
-
+ This is because record definitions are only available
+ at compile time, not at runtime. For details on records
+ in the shell, see the
+ shell(3)
+ manual page in stdlib .
@@ -98,12 +101,12 @@ person
> #person{phone=[0,8,2,3,4,3,1,2], name="Robert"}.
#person{name = "Robert",phone = [0,8,2,3,4,3,1,2],address = undefined}
- Since the address field was omitted, its default value
+
As the address field was omitted, its default value
is used.
- There is a new feature introduced in Erlang 5.1/OTP R8B,
- with which you can set a value to all fields in a record,
- overriding the defaults in the record specification. The special
- field _ , means "all fields not explicitly specified".
+ From Erlang 5.1/OTP R8B, a value to all
+ fields in a record can be set with the special field _ .
+ _ means "all fields not explicitly specified".
+ Example:
> #person{name = "Jakob", _ = '_'}.
#person{name = "Jakob",phone = '_',address = '_'}
@@ -114,6 +117,7 @@ person
The following example shows how to access a record field:
> P = #person{name = "Joe", phone = [0,8,2,3,4,3,1,2]}.
#person{name = "Joe",phone = [0,8,2,3,4,3,1,2],address = undefined}
@@ -123,6 +127,7 @@ person
The following example shows how to update a record:
> P1 = #person{name="Joe", phone=[1,2,3], address="A street"}.
#person{name = "Joe",phone = [1,2,3],address = "A street"}
@@ -133,7 +138,7 @@ person
The following example shows that the guard succeeds if
-
foo(P) when is_record(P, person) -> a_person; foo(_) -> not_a_person.@@ -141,7 +146,7 @@ foo(_) -> not_a_person.
Matching can be used in combination with records as shown in +
Matching can be used in combination with records, as shown in the following example:
> P3 = #person{name="Joe", phone=[0,0,7], address="A street"}.
@@ -163,7 +168,7 @@ find_phone([], Name) ->
Nested Records
- The value of a field in a record might be an instance of a
+
The value of a field in a record can be an instance of a
record. Retrieval of nested data can be done stepwise, or in a
single step, as shown in the following example:
@@ -173,11 +178,12 @@ find_phone([], Name) ->
demo() ->
P = #person{name= #name{first="Robert",last="Virding"}, phone=123},
First = (P#person.name)#name.first.
- In this example, demo() evaluates to "Robert" .
+ Here, demo() evaluates to "Robert" .
- Example
+ A Longer Example
+ Comments are embedded in the following example:
%% File: person.hrl
--
cgit v1.2.3
From e16e17d8ec2085b418cfa807a1bcbf0268f1d836 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?=
Date: Wed, 11 Mar 2015 11:47:13 +0100
Subject: Replace mention of a tuple fun with an external fun
---
system/doc/programming_examples/funs.xmlsrc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'system/doc/programming_examples')
diff --git a/system/doc/programming_examples/funs.xmlsrc b/system/doc/programming_examples/funs.xmlsrc
index e4f5c9c9c9..7bcf2e6171 100644
--- a/system/doc/programming_examples/funs.xmlsrc
+++ b/system/doc/programming_examples/funs.xmlsrc
@@ -127,7 +127,7 @@ F = fun FunctionName/Arity
It is also possible to refer to a function defined in a different module,
with the following syntax:
-F = {Module, FunctionName}
+F = fun Module:FunctionName/Arity
In this case, the function must be exported from the module in
question.
The following program illustrates the different ways of creating
--
cgit v1.2.3
From 2daff33c1cee100e7e8851cef463bda7c0237310 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?=
Date: Wed, 11 Mar 2015 11:50:34 +0100
Subject: Remove an historical note about fun representation before R6B
It is hardly useful to mention that funs used to be represented
as tuples in ancient releases.
---
system/doc/programming_examples/funs.xmlsrc | 4 ----
1 file changed, 4 deletions(-)
(limited to 'system/doc/programming_examples')
diff --git a/system/doc/programming_examples/funs.xmlsrc b/system/doc/programming_examples/funs.xmlsrc
index 7bcf2e6171..57b90ccf7c 100644
--- a/system/doc/programming_examples/funs.xmlsrc
+++ b/system/doc/programming_examples/funs.xmlsrc
@@ -149,10 +149,6 @@ f(N, _) when is_integer(N) ->
erlang:fun_to_list/1 returns a textual representation of a fun.
The check_process_code/2 BIF returns true if the process
contains funs that depend on the old version of a module.
-
- In OTP R5 and earlier releases, funs were represented using
- tuples.
-
--
cgit v1.2.3
From 0a1d39481440eb033f48fbbc8889bc99eda85d41 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?=
Date: Wed, 11 Mar 2015 12:02:26 +0100
Subject: Replace "lambda head" with "fun" in compiler warning
We no longer use the term "lambda".
---
system/doc/programming_examples/funs.xmlsrc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'system/doc/programming_examples')
diff --git a/system/doc/programming_examples/funs.xmlsrc b/system/doc/programming_examples/funs.xmlsrc
index 57b90ccf7c..d4c32bc854 100644
--- a/system/doc/programming_examples/funs.xmlsrc
+++ b/system/doc/programming_examples/funs.xmlsrc
@@ -190,7 +190,7 @@ print_list(File, List) ->
the following diagnostic:
./FileName.erl:Line: Warning: variable 'File'
- shadowed in 'lambda head'
+ shadowed in 'fun'
This indicates that the variable File , which is defined
inside the fun, collides with the variable File , which is
defined outside the fun.
--
cgit v1.2.3
From 61238a7e295a55f7c3dfe047b689e76452ce8c52 Mon Sep 17 00:00:00 2001
From: Hans Bolinder
Date: Tue, 17 Mar 2015 10:54:29 +0100
Subject: Correct links in the system documentation
---
system/doc/programming_examples/bit_syntax.xml | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
(limited to 'system/doc/programming_examples')
diff --git a/system/doc/programming_examples/bit_syntax.xml b/system/doc/programming_examples/bit_syntax.xml
index 7ede5b71f9..f97f171a69 100644
--- a/system/doc/programming_examples/bit_syntax.xml
+++ b/system/doc/programming_examples/bit_syntax.xml
@@ -4,7 +4,7 @@
- 2003 2013
+ 2003 2015
Ericsson AB. All Rights Reserved.
@@ -331,7 +331,8 @@ triples_to_bin([], Acc) ->
In previous releases, this function was highly inefficient, because
the binary constructed so far (Acc ) was copied in each recursion step.
That is no longer the case. For more information, see
- Efficiency Guide .
+
+ Efficiency Guide .
--
cgit v1.2.3
From fb60e5143c2faaf185816b8069174723df5f2c9f Mon Sep 17 00:00:00 2001
From: Yoshihiro Tanaka
Date: Sat, 13 Jun 2015 13:52:09 -0700
Subject: Add the link to Fun expressions manual page
---
system/doc/programming_examples/funs.xmlsrc | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
(limited to 'system/doc/programming_examples')
diff --git a/system/doc/programming_examples/funs.xmlsrc b/system/doc/programming_examples/funs.xmlsrc
index d4c32bc854..80877f0164 100644
--- a/system/doc/programming_examples/funs.xmlsrc
+++ b/system/doc/programming_examples/funs.xmlsrc
@@ -111,7 +111,9 @@ foreach(fun(Pid) -> Pid ! M end, L)
Syntax of Funs
- Funs are written with the following syntax:
+ Funs are written with the following syntax (see Fun Expressions
+ for full description):
F = fun (Arg1, Arg2, ... ArgN) ->
...
--
cgit v1.2.3
From 738c34d4bb8f1a3811acd00af8c6c12107f8315b Mon Sep 17 00:00:00 2001
From: Bruce Yinhe
Date: Thu, 18 Jun 2015 11:31:02 +0200
Subject: Change license text to APLv2
---
system/doc/programming_examples/Makefile | 21 +++++++++++----------
system/doc/programming_examples/bit_syntax.xml | 21 +++++++++++----------
system/doc/programming_examples/book.xml | 21 +++++++++++----------
system/doc/programming_examples/funs.xmlsrc | 21 +++++++++++----------
.../programming_examples/list_comprehensions.xml | 21 +++++++++++----------
system/doc/programming_examples/part.xml | 21 +++++++++++----------
system/doc/programming_examples/records.xml | 21 +++++++++++----------
system/doc/programming_examples/xmlfiles.mk | 21 +++++++++++----------
8 files changed, 88 insertions(+), 80 deletions(-)
(limited to 'system/doc/programming_examples')
diff --git a/system/doc/programming_examples/Makefile b/system/doc/programming_examples/Makefile
index 41c27ed0dd..e5f7a330f4 100644
--- a/system/doc/programming_examples/Makefile
+++ b/system/doc/programming_examples/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2003-2012. All Rights Reserved.
#
-# 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.
#
# %CopyrightEnd%
#
diff --git a/system/doc/programming_examples/bit_syntax.xml b/system/doc/programming_examples/bit_syntax.xml
index f97f171a69..0af295b7b7 100644
--- a/system/doc/programming_examples/bit_syntax.xml
+++ b/system/doc/programming_examples/bit_syntax.xml
@@ -8,16 +8,17 @@
Ericsson AB. All Rights Reserved.
- 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.
diff --git a/system/doc/programming_examples/book.xml b/system/doc/programming_examples/book.xml
index fd430a02c0..c6eb4fec97 100644
--- a/system/doc/programming_examples/book.xml
+++ b/system/doc/programming_examples/book.xml
@@ -8,16 +8,17 @@
Ericsson AB. All Rights Reserved.
- 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.
diff --git a/system/doc/programming_examples/funs.xmlsrc b/system/doc/programming_examples/funs.xmlsrc
index 80877f0164..8469f0871c 100644
--- a/system/doc/programming_examples/funs.xmlsrc
+++ b/system/doc/programming_examples/funs.xmlsrc
@@ -8,16 +8,17 @@
Ericsson AB. All Rights Reserved.
- 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.
diff --git a/system/doc/programming_examples/list_comprehensions.xml b/system/doc/programming_examples/list_comprehensions.xml
index 5b33b14dea..5667571ec5 100644
--- a/system/doc/programming_examples/list_comprehensions.xml
+++ b/system/doc/programming_examples/list_comprehensions.xml
@@ -8,16 +8,17 @@
Ericsson AB. All Rights Reserved.
- 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.
diff --git a/system/doc/programming_examples/part.xml b/system/doc/programming_examples/part.xml
index 9329717ce4..e1f8cc5d57 100644
--- a/system/doc/programming_examples/part.xml
+++ b/system/doc/programming_examples/part.xml
@@ -8,16 +8,17 @@
Ericsson AB. All Rights Reserved.
- 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.
diff --git a/system/doc/programming_examples/records.xml b/system/doc/programming_examples/records.xml
index ffcc05e758..6bda6dc0fd 100644
--- a/system/doc/programming_examples/records.xml
+++ b/system/doc/programming_examples/records.xml
@@ -8,16 +8,17 @@
Ericsson AB. All Rights Reserved.
- 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.
diff --git a/system/doc/programming_examples/xmlfiles.mk b/system/doc/programming_examples/xmlfiles.mk
index 5eb42a2881..cc77f48253 100644
--- a/system/doc/programming_examples/xmlfiles.mk
+++ b/system/doc/programming_examples/xmlfiles.mk
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2009. All Rights Reserved.
#
-# 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.
#
# %CopyrightEnd%
#
--
cgit v1.2.3