diff options
Diffstat (limited to 'system')
34 files changed, 1367 insertions, 555 deletions
diff --git a/system/doc/design_principles/applications.xml b/system/doc/design_principles/applications.xml index 228ca1f2bf..7b030115df 100644 --- a/system/doc/design_principles/applications.xml +++ b/system/doc/design_principles/applications.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>1997</year><year>2013</year> + <year>1997</year><year>2014</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -157,8 +157,9 @@ ch_app:stop([])</code> all applications have dependencies to at least <c>kernel</c> and <c>stdlib</c>.</item> </taglist> - <p>The syntax and contents of of the application resource file - are described in detail in <c>app(4)</c>.</p> + <note><p>The syntax and contents of of the application resource file + are described in detail in the<seealso marker="kernel:app"> + Application resource file reference</seealso>.</p></note> </section> <section> diff --git a/system/doc/design_principles/release_handling.xml b/system/doc/design_principles/release_handling.xml index 2a5831b89f..9d1e2c8669 100644 --- a/system/doc/design_principles/release_handling.xml +++ b/system/doc/design_principles/release_handling.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2003</year><year>2013</year> + <year>2003</year><year>2014</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -310,7 +310,7 @@ the following instruction is used:</p> <code type="none"> {apply, {M, F, A}}</code> - <p>The release handler will evalute <c>apply(M, F, A)</c>.</p> + <p>The release handler will evaluate <c>apply(M, F, A)</c>.</p> </section> <section> @@ -329,15 +329,28 @@ automatically ensured.</p> <p>When the release handler encounters the instruction, it first generates a temporary boot file, which starts the new versions - of the emulator and the core applications. Then it shuts down + of the emulator and the core applications, and the old version + of all other applications. Then it shuts down the current emulator by calling <c>init:reboot()</c>, see <c>init(3)</c>. All processes are terminated gracefully and the system is rebooted by the heart program, using the temporary boot file. After the reboot, the rest of the relup instructions are executed. This is done as a part of the temporary boot script.</p> + <warning> + <p>Since this mechanism causes the new versions of the + emulator and core applications to run with the old version of + other applications during startup, extra care must be taken to + avoid incompatibility. Incompatible changes in the core + applications may in some situations be necessary. If possible, + such changes are preceded by deprecation over two major + releases before the actual change. To make sure your + application is not crashed by an incompatible change, always + remove any call to deprecated functions as soon as + possible.</p> + </warning> <p>An info report is written when the upgrade is completed. To - programatically find out if the upgrade is complete, + programmatically find out if the upgrade is complete, call <c>release_handler:which_releases(current)</c> and check if it returns the expected (i.e. the new) release.</p> <p>The new release version must be made permanent when the new diff --git a/system/doc/design_principles/spec_proc.xml b/system/doc/design_principles/spec_proc.xml index 8de7a5fe03..e4fb5fdca7 100644 --- a/system/doc/design_principles/spec_proc.xml +++ b/system/doc/design_principles/spec_proc.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>1997</year><year>2013</year> + <year>1997</year><year>2014</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -130,7 +130,8 @@ ok -export([alloc/0, free/1]). -export([init/1]). -export([system_continue/3, system_terminate/4, - write_debug/3]). + write_debug/3, + system_get_state/1, system_replace_state/2]). start_link() -> proc_lib:start_link(ch4, init, [self()]). @@ -156,15 +157,15 @@ init(Parent) -> loop(Chs, Parent, Deb) -> receive {From, alloc} -> - Deb2 = sys:handle_debug(Deb, {ch4, write_debug}, + Deb2 = sys:handle_debug(Deb, fun ch4:write_debug/3, ch4, {in, alloc, From}), {Ch, Chs2} = alloc(Chs), From ! {ch4, Ch}, - Deb3 = sys:handle_debug(Deb2, {ch4, write_debug}, + Deb3 = sys:handle_debug(Deb2, fun ch4:write_debug/3, ch4, {out, {ch4, Ch}, From}), loop(Chs2, Parent, Deb3); {free, Ch} -> - Deb2 = sys:handle_debug(Deb, {ch4, write_debug}, + Deb2 = sys:handle_debug(Deb, fun ch4:write_debug/3, ch4, {in, {free, Ch}}), Chs2 = free(Ch, Chs), loop(Chs2, Parent, Deb2); @@ -177,9 +178,16 @@ loop(Chs, Parent, Deb) -> system_continue(Parent, Deb, Chs) -> loop(Chs, Parent, Deb). -system_terminate(Reason, Parent, Deb, Chs) -> +system_terminate(Reason, _Parent, _Deb, _Chs) -> exit(Reason). +system_get_state(Chs) -> + {ok, Chs}. + +system_replace_state(StateFun, Chs) -> + NChs = StateFun(Chs), + {ok, NChs, NChs}. + write_debug(Dev, Event, Name) -> io:format(Dev, "~p event = ~p~n", [Name, Event]).</pre> <p>Example on how the simple debugging functions in <c>sys</c> can @@ -281,10 +289,10 @@ sys:handle_debug(Deb, Func, Info, Event) => Deb1</code> <p><c>Deb</c> is the debug structure.</p> </item> <item> - <p><c>Func</c> is a tuple <c>{Module, Name}</c> (or a fun) and - should specify a (user defined) function used to format + <p><c>Func</c> is a fun specifying + a (user defined) function used to format trace output. For each system event, the format function is - called as <c>Module:Name(Dev, Event, Info)</c>, where:</p> + called as <c>Func(Dev, Event, Info)</c>, where:</p> <list type="bulleted"> <item> <p><c>Dev</c> is the IO device to which the output should @@ -319,15 +327,15 @@ sys:handle_debug(Deb, Func, Info, Event) => Deb1</code> loop(Chs, Parent, Deb) -> receive {From, alloc} -> - Deb2 = sys:handle_debug(Deb, {ch4, write_debug}, + Deb2 = sys:handle_debug(Deb, fun ch4:write_debug/3, ch4, {in, alloc, From}), {Ch, Chs2} = alloc(Chs), From ! {ch4, Ch}, - Deb3 = sys:handle_debug(Deb2, {ch4, write_debug}, + Deb3 = sys:handle_debug(Deb2, fun ch4:write_debug/3, ch4, {out, {ch4, Ch}, From}), loop(Chs2, Parent, Deb3); {free, Ch} -> - Deb2 = sys:handle_debug(Deb, {ch4, write_debug}, + Deb2 = sys:handle_debug(Deb, fun ch4:write_debug/3, ch4, {in, {free, Ch}}), Chs2 = free(Ch, Chs), loop(Chs2, Parent, Deb2); @@ -366,8 +374,15 @@ Module:system_terminate(Reason, Parent, Deb, State)</code> <item><c>Module</c> is the name of the module.</item> <item><c>Deb</c> is the debug structure.</item> <item><c>State</c> is a term describing the internal state and - is passed to <c>system_continue</c>/<c>system_terminate</c>.</item> + is passed to <c>system_continue</c>/<c>system_terminate</c>/ + <c>system_get_state</c>/<c>system_replace_state</c>.</item> </list> + <p>If the process should return its state <c>handle_system_msg</c> will call:</p> + <code type="none"> +Module:system_get_state(State)</code> + <p>or if the process should replace its state using the fun <c>StateFun</c>:</p> + <code type="none"> +Module:system_replace_state(StateFun, State)</code> <p>In the example:</p> <code type="none"> loop(Chs, Parent, Deb) -> @@ -383,7 +398,15 @@ system_continue(Parent, Deb, Chs) -> loop(Chs, Parent, Deb). system_terminate(Reason, Parent, Deb, Chs) -> - exit(Reason).</code> + exit(Reason). + +system_get_state(Chs) -> + {ok, Chs, Chs}. + +system_replace_state(StateFun, Chs) -> + NChs = StateFun(Chs), + {ok, NChs, NChs}. +</code> <p>If the special process is set to trap exits, note that if the parent process terminates, the expected behavior is to terminate with the same reason:</p> @@ -408,11 +431,11 @@ loop(...) -> <section> <title>User-Defined Behaviours</title> - <p>To implement a user-defined behaviour, write code similar to + <p><marker id="behaviours"/>To implement a user-defined behaviour, write code similar to code for a special process but calling functions in a callback module for handling specific tasks.</p> <p>If it is desired that the compiler should warn for missing callback - functions, as it does for the OTP behaviours, add callback attributes in the + functions, as it does for the OTP behaviours, add <c>-callback</c> attributes in the behaviour module to describe the expected callbacks:</p> <code type="none"> -callback Name1(Arg1_1, Arg1_2, ..., Arg1_N1) -> Res1. @@ -422,15 +445,15 @@ loop(...) -> <p>where <c>NameX</c> are the names of the expected callbacks and <c>ArgX_Y</c>, <c>ResX</c> are types as they are described in Specifications for functions in <seealso marker="../reference_manual/typespec">Types and - Function Specifications</seealso>. The whole syntax of spec attributes is - supported by callback attributes.</p> + Function Specifications</seealso>. The whole syntax of <c>-spec</c> attribute is + supported by <c>-callback</c> attribute.</p> <p>Alternatively you may directly implement and export the function:</p> <code type="none"> behaviour_info(callbacks) -> - [{Name1,Arity1},...,{NameN,ArityN}].</code> - <p>where each <c>{Name,Arity}</c> specifies the name and arity of a callback + [{Name1, Arity1},...,{NameN, ArityN}].</code> + <p>where each <c>{Name, Arity}</c> specifies the name and arity of a callback function. This function is otherwise automatically generated by the compiler - using the callback attributes.</p> + using the <c>-callback</c> attributes.</p> <p>When the compiler encounters the module attribute <c>-behaviour(Behaviour).</c> in a module <c>Mod</c>, it will call <c>Behaviour:behaviour_info(callbacks)</c> and compare the result with the diff --git a/system/doc/efficiency_guide/advanced.xml b/system/doc/efficiency_guide/advanced.xml index b5771a5929..51f1b2612c 100644 --- a/system/doc/efficiency_guide/advanced.xml +++ b/system/doc/efficiency_guide/advanced.xml @@ -183,7 +183,7 @@ On 64-bit architectures: 4 words for a reference from the current local node, an <tag><em>Open ports</em></tag> <item> <marker id="ports"></marker> - <p>The maximum number of simultaneously oper Erlang ports is + <p>The maximum number of simultaneously open Erlang ports is often by default 16384. This limit can be configured at startup, for more information see the <seealso marker="erts:erl#max_ports"><c>+Q</c></seealso> diff --git a/system/doc/efficiency_guide/binaryhandling.xml b/system/doc/efficiency_guide/binaryhandling.xml index 6b0df49011..4ba1378059 100644 --- a/system/doc/efficiency_guide/binaryhandling.xml +++ b/system/doc/efficiency_guide/binaryhandling.xml @@ -5,7 +5,7 @@ <header> <copyright> <year>2007</year> - <year>2013</year> + <year>2014</year> <holder>Ericsson AB, All Rights Reserved</holder> </copyright> <legalnotice> @@ -237,8 +237,9 @@ Bin = <<Bin1,...>> %% Bin1 will be COPIED <p><c>Bin1</c> will be copied in the third line.</p> <p>The same thing happens if you insert a binary into an <em>ets</em> - table or send it to a port using <c>erlang:port_command/2</c>.</p> - + table or send it to a port using <c>erlang:port_command/2</c> or pass it to + <seealso marker="erts:erl_nif#enif_inspect_binary">enif_inspect_binary</seealso> + in a NIF.</p> <p>Matching a binary will also cause it to shrink and the next append operation will copy the binary data:</p> diff --git a/system/doc/efficiency_guide/processes.xml b/system/doc/efficiency_guide/processes.xml index 6f85b029eb..86951e2dcc 100644 --- a/system/doc/efficiency_guide/processes.xml +++ b/system/doc/efficiency_guide/processes.xml @@ -186,7 +186,7 @@ kilo_byte(0, Acc) -> kilo_byte(N, Acc) -> kilo_byte(N-1, [Acc|Acc]).</code> - <p><c>kilo_byte/1</c> creates a deep list. If we call + <p><c>kilo_byte/0</c> creates a deep list. If we call <c>list_to_binary/1</c>, we can convert the deep list to a binary of 1024 bytes:</p> diff --git a/system/doc/efficiency_guide/tablesDatabases.xml b/system/doc/efficiency_guide/tablesDatabases.xml index 5b0df76371..94c921fa1c 100644 --- a/system/doc/efficiency_guide/tablesDatabases.xml +++ b/system/doc/efficiency_guide/tablesDatabases.xml @@ -136,7 +136,7 @@ print_person(PersonId) -> io:format("No person with ID = ~p~n", [PersonID]) end. -%%% Internal functionss +%%% Internal functions print_name(PersonID) -> [Person] = ets:lookup(person, PersonId), io:format("No person ~p~n", [Person#person.name]). diff --git a/system/doc/getting_started/conc_prog.xml b/system/doc/getting_started/conc_prog.xml index e392287ff0..2b64826a93 100644 --- a/system/doc/getting_started/conc_prog.xml +++ b/system/doc/getting_started/conc_prog.xml @@ -95,7 +95,7 @@ goodbye</pre> the second a "goodbye", the first another "hello" and so forth. But where did the <0.63.0> come from? The return value of a function is of course the return value of the last "thing" in - the function. The last thing in the function <c>start</c> is</p> + the function. The last thing in the function <c>start</c> is:</p> <code type="none"> spawn(tut14, say_something, [goodbye, 3]).</code> <p><c>spawn</c> returns a <em>process identifier</em>, or @@ -166,11 +166,11 @@ Pong_PID = spawn(tut15, pong, [])</code> <c>start</c> now creates another process "ping".</p> <code type="none"> spawn(tut15, ping, [3, Pong_PID]),</code> - <p>this process executes</p> + <p>This process executes:</p> <code type="none"> tut15:ping(3, Pong_PID)</code> <p><0.36.0> is the return value from the <c>start</c> function.</p> - <p>The process "pong" now does:</p> + <p>The process "pong" now does:</p> <code type="none"> receive finished -> @@ -235,7 +235,7 @@ Ping_PID ! pong</code> Pid ! Message</code> <p>I.e. <c>Message</c> (any Erlang term) is sent to the process with identity <c>Pid</c>.</p> - <p>After sending the message <c>pong</c>, to the process "ping", + <p>After sending the message <c>pong</c> to the process "ping", "pong" calls the <c>pong</c> function again, which causes it to get back to the <c>receive</c> again and wait for another message. Now let's look at the process "ping". Recall that it was started @@ -253,7 +253,7 @@ Pong_PID ! {ping, self()},</code> <p><c>self()</c> returns the pid of the process which executes <c>self()</c>, in this case the pid of "ping". (Recall the code for "pong", this will land up in the variable <c>Ping_PID</c> in - the <c>receive</c> previously explained).</p> + the <c>receive</c> previously explained.)</p> <p>"Ping" now waits for a reply from "pong":</p> <code type="none"> receive @@ -352,8 +352,8 @@ pong ! {ping, self()},</code> on different computers. Before we do this, there are a few things we need to set up to get this to work. The distributed Erlang implementation provides a basic security mechanism to prevent - unauthorized access to an Erlang system on another computer - (*manual*). Erlang systems which talk to each other must have + unauthorized access to an Erlang system on another computer. + Erlang systems which talk to each other must have the same <em>magic cookie</em>. The easiest way to achieve this is by having a file called <c>.erlang.cookie</c> in your home directory on all machines which on which you are going to run @@ -363,8 +363,8 @@ pong ! {ping, self()},</code> you can safely ignore this and simply create a file called <c>.erlang.cookie</c> in the directory you get to after executing the command <c>cd</c> without any argument). - The <c>.erlang.cookie</c> file should contain on line with - the same atom. For example on Linux or Unix in the OS shell:</p> + The <c>.erlang.cookie</c> file should contain one line with + the same atom. For example, on Linux or Unix in the OS shell:</p> <pre> $ <input>cd</input> $ <input>cat > .erlang.cookie</input> @@ -373,10 +373,10 @@ $ <input>chmod 400 .erlang.cookie</input></pre> <p>The <c>chmod</c> above make the <c>.erlang.cookie</c> file accessible only by the owner of the file. This is a requirement.</p> <p>When you start an Erlang system which is going to talk to other - Erlang systems, you must give it a name, eg: </p> + Erlang systems, you must give it a name, e.g.: </p> <pre> $ <input>erl -sname my_name</input></pre> - <p>We will see more details of this later (*manual*). If you want to + <p>We will see more details of this later. If you want to experiment with distributed Erlang, but you only have one computer to work on, you can start two separate Erlang systems on the same computer but give them different names. Each Erlang @@ -385,7 +385,7 @@ $ <input>erl -sname my_name</input></pre> IP domain and we can use only the first component of the IP address, if we want to use nodes in different domains we use <c>-name</c> instead, but then all IP address must be given in - full (*manual*).</p> + full.)</p> <p>Here is the ping pong example modified to run on two separate nodes:</p> <code type="none"> @@ -538,9 +538,9 @@ ping finished</pre> <p>Before we start, let's note the following:</p> <list type="bulleted"> <item> - <p>This example will just show the message passing logic no + <p>This example will just show the message passing logic - no attempt at all has been made to provide a nice graphical user - interface - this can of course also be done in Erlang - but + interface. This can, of course, also be done in Erlang - but that's another tutorial.</p> </item> <item> @@ -550,8 +550,8 @@ ping finished</pre> tutorial.</p> </item> <item> - <p>The first program we write will contain some inadequacies as - regards handling of nodes which disappear, we will correct + <p>The first program we write will contain some inadequacies + regarding the handling of nodes which disappear. We will correct these in a later version of the program.</p> </item> </list> @@ -571,7 +571,7 @@ ping finished</pre> %%% already logged in at the same node, login will be rejected %%% with a suitable error message. %%% logoff() -%%% Logs off anybody at at node +%%% Logs off anybody at that node %%% message(ToName, Message) %%% sends Message to ToName. Error messages if the user of this %%% function is not logged on or if ToName is not logged on at @@ -734,11 +734,11 @@ await_result() -> <item>copy the compiled code (<c>messenger.beam</c>) to the directory on each computer where you start Erlang.</item> </list> - <p>In the following example of use of this program, I have started + <p>In the following example of use of this program I have started nodes on four different computers, but if you don't have that - many machines available on your network, you could start up + many machines available on your network you could start up several nodes on the same machine.</p> - <p>We start up four Erlang nodes, messenger@super, c1@bilbo, + <p>We start up four Erlang nodes: messenger@super, c1@bilbo, c2@kosken, c3@gollum.</p> <p>First we start up a the server at messenger@super:</p> <pre> @@ -780,19 +780,19 @@ ok receiver_not_found</pre> <p>But this fails as Fred has already logged off.</p> <p>First let's look at some of the new concepts we have introduced.</p> - <p>There are two versions of the <c>server_transfer</c> function, + <p>There are two versions of the <c>server_transfer</c> function: one with four arguments (<c>server_transfer/4</c>) and one with five (<c>server_transfer/5</c>). These are regarded by Erlang as two separate functions.</p> <p>Note how we write the <c>server</c> function so that it calls - itself, <c>server(User_List)</c> and thus creates a loop. + itself, via <c>server(User_List)</c>, and thus creates a loop. The Erlang compiler is "clever" and optimizes the code so that this really is a sort of loop and not a proper function call. But this only works if there is no code after the call, otherwise the compiler will expect the call to return and make a proper function call. This would result in the process getting bigger and bigger for every loop.</p> - <p>We use functions in the <c>lists</c> module. This is a very + <p>We use functions from the <c>lists</c> module. This is a very useful module and a study of the manual page is recommended (<c>erl -man lists</c>). <c>lists:keymember(Key,Position,Lists)</c> looks through a list diff --git a/system/doc/getting_started/records_macros.xml b/system/doc/getting_started/records_macros.xml index 76e3d185fb..73c8ce5c8d 100644 --- a/system/doc/getting_started/records_macros.xml +++ b/system/doc/getting_started/records_macros.xml @@ -97,7 +97,7 @@ %%% with a suitable error message. %%% logoff() -%%% Logs off anybody at at node +%%% Logs off anybody at that node %%% message(ToName, Message) %%% sends Message to ToName. Error messages if the user of this @@ -284,7 +284,7 @@ server_transfer(From, Name, To, Message, User_List) -> the record is referred to. If you leave out a field when creating a record, it will get the value of the atom undefined. (*manual*)</p> <p>Pattern matching with records is very similar to creating - records. For example inside a <c>case</c> or <c>receive</c>:</p> + records. For example, inside a <c>case</c> or <c>receive</c>:</p> <code type="none"> #message_to{to_name=ToName, message=Message} -></code> <p>is the same as:</p> diff --git a/system/doc/getting_started/robustness.xml b/system/doc/getting_started/robustness.xml index 359ea93275..e8fb81d5e8 100644 --- a/system/doc/getting_started/robustness.xml +++ b/system/doc/getting_started/robustness.xml @@ -30,7 +30,7 @@ </header> <p>There are several things which are wrong with the <seealso marker="conc_prog#ex">messenger example</seealso> from - the previous chapter. For example if a node where a user is logged + the previous chapter. For example, if a node where a user is logged on goes down without doing a log off, the user will remain in the server's <c>User_List</c> but the client will disappear thus making it impossible for the user to log on again as the server @@ -214,9 +214,9 @@ Ping received pong</pre> signal to be sent to "pong" which will also terminate.</p> <p>It is possible to modify the default behaviour of a process so that it does not get killed when it receives abnormal exit - signals, but all signals will be turned into normal messages on + signals, but all signals will be turned into normal messages with the format <c>{'EXIT',FromPID,Reason}</c> and added to the end of - the receiving processes message queue. This behaviour is set by:</p> + the receiving process' message queue. This behaviour is set by:</p> <code type="none"> process_flag(trap_exit, true)</code> <p>There are several other process flags, see @@ -289,7 +289,7 @@ pong exiting, got {'EXIT',<3820.39.0>,ping}</pre> %%% already logged in at the same node, login will be rejected %%% with a suitable error message. %%% logoff() -%%% Logs off anybody at at node +%%% Logs off anybody at that node %%% message(ToName, Message) %%% sends Message to ToName. Error messages if the user of this %%% function is not logged on or if ToName is not logged on at diff --git a/system/doc/getting_started/seq_prog.xml b/system/doc/getting_started/seq_prog.xml index 3830a34e5a..699b9487ed 100644 --- a/system/doc/getting_started/seq_prog.xml +++ b/system/doc/getting_started/seq_prog.xml @@ -31,14 +31,14 @@ <section> <title>The Erlang Shell</title> - <p>Most operating systems have a command interpreter or shell, Unix - and Linux have many, Windows has the Command Prompt. Erlang has + <p>Most operating systems have a command interpreter or shell- Unix + and Linux have many, while Windows has the Command Prompt. Erlang has its own shell where you can directly write bits of Erlang code and evaluate (run) them to see what happens (see <seealso marker="stdlib:shell">shell(3)</seealso>). Start the Erlang shell (in Linux or UNIX) by starting a shell or command interpreter in your operating system and typing - <c>erl</c>, you will see something like this.</p> + <c>erl</c>. You will see something like this.</p> <pre> % <input>erl</input> Erlang R15B (erts-5.9.1) [source] [smp:8:8] [rq:8] [async-threads:0] [hipe] [kernel-poll:false] @@ -62,7 +62,7 @@ Eshell V5.9.1 (abort with ^G) (See the chapter <seealso marker="erts:tty">"tty - A command line interface"</seealso> in ERTS User's Guide).</p> <p>(Note: you will find a lot of line numbers given by the shell out of sequence in this tutorial as it was written and the code - tested in several sessions).</p> + tested in several sessions.)</p> <p>Now let's try a more complex calculation.</p> <pre> 2> <input>(42 + 77) * 66 / 3.</input> @@ -115,7 +115,7 @@ double(X) -> entered and there will also be error messages to give you some idea as to what has gone wrong so you can change what you have written and try again.</p> - <p>Now lets run the program.</p> + <p>Now let's run the program.</p> <pre> 4> <input>tut:double(10).</input> 20</pre> @@ -208,7 +208,7 @@ mult(X, Y) -> called variables. Variables must start with a capital letter (see the chapter <seealso marker="doc/reference_manual:expressions">"Variables"</seealso> - in the Erlang Reference Manual). Examples of variable could be + in the Erlang Reference Manual). Examples of variables could be <c>Number</c>, <c>ShoeSize</c>, <c>Age</c> etc.</p> </section> @@ -271,7 +271,7 @@ convert(N, centimeter) -> Consider:</p> <code type="none"> tut2:convert(3, inch).</code> - <p>Does this mean that 3 is in inches? or that 3 is in centimeters + <p>Does this mean that 3 is in inches? Or that 3 is in centimeters and we want to convert it to inches? So Erlang has a way to group things together to make things more understandable. We call these <em>tuples</em>. Tuples are surrounded by "{" and "}".</p> @@ -309,7 +309,7 @@ convert_length({inch, Y}) -> <p>We have shown tuples with two parts above, but tuples can have as many parts as we want and contain any valid Erlang <em>term</em>. For example, to represent the temperature of - various cities of the world we could write</p> + various cities of the world we could write:</p> <code type="none"> {moscow, {c, -10}} {cape_town, {f, 70}} @@ -325,7 +325,7 @@ convert_length({inch, Y}) -> <title>Lists</title> <p>Whereas tuples group things together, we also want to be able to represent lists of things. Lists in Erlang are surrounded by "[" - and "]". For example a list of the temperatures of various cities + and "]". For example, a list of the temperatures of various cities in the world could be:</p> <code type="none"> [{moscow, {c, -10}}, {cape_town, {f, 70}}, {stockholm, {c, -4}}, @@ -345,7 +345,7 @@ convert_length({inch, Y}) -> [2,3,4,5]</pre> <p>We use | to separate the first elements of the list from the rest of the list. (<c>First</c> has got value 1 and - <c>TheRest</c> value [2,3,4,5]).</p> + <c>TheRest</c> value [2,3,4,5].)</p> <p>Another example:</p> <pre> 20> <input>[E1, E2 | R] = [1,2,3,4,5,6,7].</input> @@ -403,7 +403,7 @@ list_length([First | Rest]) -> the remaining elements <c>Rest</c> is 1 + the length of <c>Rest</c>.</p> <p>(Advanced readers only: This is not tail recursive, there is a - better way to write this function).</p> + better way to write this function.)</p> <p>In general we can say we use tuples where we would use "records" or "structs" in other languages and we use lists when we want to represent things which have varying sizes, (i.e. where we would @@ -419,6 +419,129 @@ list_length([First | Rest]) -> </section> <section> + <title>Maps</title> + <p>Maps are a set of key to value associations. These associations + are encapsulated with "#{" and "}". To create an association from + "key" to value 42, we write:</p> +<code type="none"> +> #{ "key" => 42 }. +#{"key" => 42}</code> + <p>We will jump straight into the deep end with an example using some + interesting features.</p> + <p>The following example shows how we calculate alpha blending using + maps to reference color and alpha channels:</p> + <code type="none"> +-module(color). + +-export([new/4, blend/2]). + +-define(is_channel(V), (is_float(V) andalso V >= 0.0 andalso V =< 1.0)). + +new(R,G,B,A) when ?is_channel(R), ?is_channel(G), + ?is_channel(B), ?is_channel(A) -> + #{red => R, green => G, blue => B, alpha => A}. + +blend(Src,Dst) -> + blend(Src,Dst,alpha(Src,Dst)). + +blend(Src,Dst,Alpha) when Alpha > 0.0 -> + Dst#{ + red := red(Src,Dst) / Alpha, + green := green(Src,Dst) / Alpha, + blue := blue(Src,Dst) / Alpha, + alpha := Alpha + }; +blend(_,Dst,_) -> + Dst#{ + red := 0.0, + green := 0.0, + blue := 0.0, + alpha := 0.0 + }. + +alpha(#{alpha := SA}, #{alpha := DA}) -> + SA + DA*(1.0 - SA). + +red(#{red := SV, alpha := SA}, #{red := DV, alpha := DA}) -> + SV*SA + DV*DA*(1.0 - SA). +green(#{green := SV, alpha := SA}, #{green := DV, alpha := DA}) -> + SV*SA + DV*DA*(1.0 - SA). +blue(#{blue := SV, alpha := SA}, #{blue := DV, alpha := DA}) -> + SV*SA + DV*DA*(1.0 - SA).</code> + <p>Compile (file <c>color.erl</c>) and test:</p> + <pre> +> <input>c(color).</input> +{ok,color} +> <input>C1 = color:new(0.3,0.4,0.5,1.0).</input> +#{alpha => 1.0,blue => 0.5,green => 0.4,red => 0.3} +> <input>C2 = color:new(1.0,0.8,0.1,0.3).</input> +#{alpha => 0.3,blue => 0.1,green => 0.8,red => 1.0} +> <input>color:blend(C1,C2).</input> +#{alpha => 1.0,blue => 0.5,green => 0.4,red => 0.3} +> <input>color:blend(C2,C1).</input> +#{alpha => 1.0,blue => 0.38,green => 0.52,red => 0.51} +</pre> + <p>This example warrants some explanation:</p> + <code type="none"> +-define(is_channel(V), (is_float(V) andalso V >= 0.0 andalso V =< 1.0)).</code> + <p> + First we define a macro <c>is_channel</c> to help with our guard tests. + This is only here for convenience and to reduce syntax cluttering. + + You can read more about <seealso marker="doc/reference_manual:macros">Macros</seealso> + in the Erlang Reference Manual. + </p> + <code type="none"> +new(R,G,B,A) when ?is_channel(R), ?is_channel(G), + ?is_channel(B), ?is_channel(A) -> + #{red => R, green => G, blue => B, alpha => A}.</code> + <p> + The function <c>new/4</c> creates a new map term with and lets the keys + <c>red</c>, <c>green</c>, <c>blue</c> and <c>alpha</c> be associated + with an initial value. In this case we only allow for float + values between and including 0.0 and 1.0 as ensured by the <c>?is_channel/1</c> macro + for each argument. Only the <c>=></c> operator is allowed when creating a new map. + </p> + <p> + By calling <c>blend/2</c> on any color term created by <c>new/4</c> we can calculate + the resulting color as determined by the two maps terms. + </p> + <p> + The first thing <c>blend/2</c> does is to calculate the resulting alpha channel. + </p> + <code type="none"> +alpha(#{alpha := SA}, #{alpha := DA}) -> + SA + DA*(1.0 - SA).</code> + <p> + We fetch the value associated with key <c>alpha</c> for both arguments using + the <c>:=</c> operator. Any other keys + in the map are ignored, only the key <c>alpha</c> is required and checked for. + </p> + <p>This is also the case for functions <c>red/2</c>, <c>blue/2</c> and <c>green/2</c>.</p> + <code type="none"> +red(#{red := SV, alpha := SA}, #{red := DV, alpha := DA}) -> + SV*SA + DV*DA*(1.0 - SA).</code> + <p> + The difference here is that we check for two keys in each map argument. The other keys + are ignored. + </p> + <p> + Finally we return the resulting color in <c>blend/3</c>. + </p> + <code type="none"> +blend(Src,Dst,Alpha) when Alpha > 0.0 -> + Dst#{ + red := red(Src,Dst) / Alpha, + green := green(Src,Dst) / Alpha, + blue := blue(Src,Dst) / Alpha, + alpha := Alpha + };</code> + <p> + We update the <c>Dst</c> map with new channel values. The syntax for updating an existing key with a new value is done with <c>:=</c> operator. + </p> + </section> + + <section> <title>Standard Modules and Manual Pages</title> <p>Erlang has a lot of standard modules to help you do things. For example, the module <c>io</c> contains a lot of functions to help @@ -450,10 +573,9 @@ http://www.erlang.org/doc/r9b/doc/index.html</code> <section> <title>Writing Output to a Terminal</title> <p>It's nice to be able to do formatted output in these example, so - the next example shows a simple way to use to use - the <c>io:format</c> function. Of course, just like all other - exported functions, you can test the <c>io:format</c> function in - the shell:</p> + the next example shows a simple way to use the <c>io:format</c> + function. Of course, just like all other exported functions, you + can test the <c>io:format</c> function in the shell:</p> <pre> 31> <input>io:format("hello world~n", []).</input> hello world @@ -550,7 +672,7 @@ ok</pre> <p>Now we call <c>format_temps(Rest)</c> with the rest of the list as an argument. This way of doing things is similar to the loop constructs in other languages. (Yes, this is recursion, but don't - let that worry you). So the same <c>format_temps</c> function is + let that worry you.) So the same <c>format_temps</c> function is called again, this time <c>City</c> gets the value <c>{cape_town,{f,70}}</c> and we repeat the same procedure as before. We go on doing this until the list becomes empty, i.e. [], @@ -614,12 +736,12 @@ list_max([Head|Rest], Result_so_far) -> the next part of the function.</p> <p>Some useful operators in guards are, < less than, > greater than, == equal, >= greater or equal, =< less or - equal, /= not equal. (see the chapter - <seealso marker="doc/reference_manual:expressions">"Guard Sequences"</seealso> in the Erlang Reference Manual).</p> + equal, /= not equal. (See the chapter + <seealso marker="doc/reference_manual:expressions">"Guard Sequences"</seealso> in the Erlang Reference Manual.)</p> <p>To change the above program to one which works out the minimum value of the element in a list, all we would need to do is to write < instead of >. (But it would be wise to change - the name of the function to <c>list_min</c> :-).</p> + the name of the function to <c>list_min</c> :-).)</p> <p>Remember that I mentioned earlier that a variable could only be given a value once in its scope? In the above we see, for example, that <c>Result_so_far</c> has been given several values. This is @@ -723,7 +845,7 @@ reverse([], [3,2,1]) => write a list manipulating function it is a good idea to check that one isn't already written for you. (see <seealso marker="stdlib:lists">lists(3)</seealso>).</p> - <p>Now lets get back to the cities and temperatures, but take a more + <p>Now let's get back to the cities and temperatures, but take a more structured approach this time. First let's convert the whole list to Celsius as follows and test the function:</p> <code type="none"> @@ -767,7 +889,7 @@ format_temps(List_of_cities) -> <code type="none"> [City | convert_list_to_c(Rest)];</code> <p>We go on doing this until we get to the end of the list (i.e. - the list is empty:</p> + the list is empty):</p> <code type="none"> convert_list_to_c([]) -> [].</code> @@ -1029,13 +1151,13 @@ month_length(Year, Month) -> <section> <title>Built In Functions (BIFs)</title> - <p>Built in functions BIFs are functions which for some reason is + <p>Built in functions (BIFs) are functions which for some reason are built in to the Erlang virtual machine. BIFs often implement functionality that is impossible to implement in Erlang or is too inefficient to implement in Erlang. Some BIFs can be called - by use of the function name only but they are by default belonging - to the erlang module so for example the call to the BIF <c>trunc</c> - below is equivalent with a call to <c>erlang:trunc</c>.</p> + by use of the function name only, but they by default belong + to the erlang module. So for example, the call to the BIF <c>trunc</c> + below is equivalent to a call to <c>erlang:trunc</c>.</p> <p>As you can see, we first find out if a year is leap or not. If a year is divisible by 400, it is a leap year. To find this out we first divide the year by 400 and use the built in function @@ -1052,23 +1174,23 @@ trunc(5.01) = 5 2000 / 400 = 5.0 trunc(5.0) = 5 5 * 400 = 2000</code> - <p>so we have a leap year. The next two tests if the year is - divisible by 100 or 4 are done in the same way. The first - <c>if</c> returns <c>leap</c> or <c>not_leap</c> which lands up + <p>so we have a leap year. The next two tests, which check if the year is + divisible by 100 or 4, are done in the same way. The first + <c>if</c> returns <c>leap</c> or <c>not_leap</c> which ends up in the variable <c>Leap</c>. We use this variable in the guard for <c>feb</c> in the following <c>case</c> which tells us how long the month is.</p> - <p>This example showed the use of <c>trunc</c>, an easier way would - be to use the Erlang operator <c>rem</c> which gives the remainder + <p>This example showed the use of <c>trunc</c>. An easier way would + be to use the Erlang operator <c>rem</c>, which gives the remainder after division. For example:</p> <pre> 74> <input>2004 rem 400.</input> 4</pre> - <p>so instead of writing</p> + <p>so instead of writing:</p> <code type="none"> trunc(Year / 400) * 400 == Year -> leap;</code> - <p>we could write</p> + <p>we could write:</p> <code type="none"> Year rem 400 == 0 -> leap;</code> @@ -1078,7 +1200,7 @@ Year rem 400 == 0 -> (see the chapter <seealso marker="doc/reference_manual:expressions">"Guard Sequences"</seealso> in the Erlang Reference Manual) (Aside for advanced readers: This is to ensure that guards don't have side - effects). Let's play with a few of these functions in the shell:</p> + effects.) Let's play with a few of these functions in the shell:</p> <pre> 75> <input>trunc(5.6).</input> 5 @@ -1145,7 +1267,7 @@ map(Fun, []) -> #Fun<erl_eval.5.123085357> 89> <input>lists:map(Add_3, [1,2,3]).</input> [4,5,6]</pre> - <p>Now lets print out the temperatures in a list of cities (yet + <p>Now let's print out the temperatures in a list of cities (yet again):</p> <pre> 90> <input>Print_City = fun({City, {X, Temp}}) -> io:format("~-15w ~w ~w~n",</input> diff --git a/system/doc/installation_guide/Makefile b/system/doc/installation_guide/Makefile index 6923f52d8a..83210bd21f 100644 --- a/system/doc/installation_guide/Makefile +++ b/system/doc/installation_guide/Makefile @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 1996-2012. All Rights Reserved. +# Copyright Ericsson AB 1996-2014. 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 @@ -58,8 +58,7 @@ XML_FILES = \ GENERATED_XML_FILES = \ INSTALL.xml \ INSTALL-CROSS.xml \ - INSTALL-WIN32.xml \ - MARKDOWN.xml + INSTALL-WIN32.xml # ---------------------------------------------------- @@ -74,8 +73,7 @@ REDIRECT_HTML_DIR = $(HTMLDIR)/source REDIRECT_HTML_FILES = \ $(REDIRECT_HTML_DIR)/INSTALL.html \ $(REDIRECT_HTML_DIR)/INSTALL-CROSS.html \ - $(REDIRECT_HTML_DIR)/INSTALL-WIN32.html \ - $(REDIRECT_HTML_DIR)/MARKDOWN.html + $(REDIRECT_HTML_DIR)/INSTALL-WIN32.html # ---------------------------------------------------- # FLAGS diff --git a/system/doc/installation_guide/install-binary.xml b/system/doc/installation_guide/install-binary.xml index 07027a39f6..af7dab6e44 100644 --- a/system/doc/installation_guide/install-binary.xml +++ b/system/doc/installation_guide/install-binary.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2000</year><year>2013</year> + <year>2000</year><year>2014</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -31,117 +31,40 @@ <rev>C</rev> <file>install-binary.xml</file> </header> - - <section> - <title>UNIX</title> - - <section> - <title>Introduction</title> - <p>The system is delivered as a single compressed tar file.</p> - <p>To browse the on-line HTML documentation, Netscape or an equivalent - browser supporting frames is needed.</p> - </section> - - <section> - <title>Installation Procedure</title> - <p>When installed, the entire system, except for a small start-up - script, resides in a single directory tree. The location of this - directory tree can be chosen arbitrarily by the installer, and it - does not need to be in the user's <c>$PATH</c>. The only requirements - are that the file system where it is placed has enough free space, - and that the users who run Erlang/OTP have read access to it. In the - example below, the directory tree is assumed to be located at - <c>/usr/local/erlang</c>, which is here called the <em>top-level directory</em>.</p> - <p>It is assumed that you have the compressed tar file, the name of - which is <c><![CDATA[<PREFIX>.tar.gz]]></c>, where <c><![CDATA[<PREFIX>]]></c> is a string - denoting the particular Erlang/OTP release, e.g. - <c>otp_LXA_11930_sunos5_R9B</c>.</p> - <p>Wherever the string <c><![CDATA[<PREFIX>]]></c> is used below, it should - be replaced by the actual name prefix of the compressed tar file.</p> - <p>The tape archive file does not have one single directory in which - all other files are rooted. Therefore the tape archive file must be - extracted into an empty (newly created) directory.</p> - <list type="ordered"> - <item> - <p>If the <em>top-level directory</em> does not already exist, - create it:</p> - <pre> -mkdir /usr/local/erlang</pre> - </item> - <item> - <p>Change the current directory to the <em>top level directory</em>:</p> - <pre> -cd /usr/local/erlang</pre> - </item> - <item> - <p>Create the <em>installation directory</em> with an appropriate - name. For example:</p> - <pre> -mkdir otp_r7b</pre> - </item> - <item> - <p>Change to the <em>installation directory</em>, e.g.</p> - <pre> -cd otp_r7b</pre> - </item> - <item> - <p>Assuming the compressed tar file resides in the directory - <c><![CDATA[<SOME-DIR>]]></c>,. extract the compressed tar file into the - current directory:</p> - <pre> -gunzip -c <SOME-DIR>/<PREFIX>.tar.gz | tar xfp -</pre> - </item> - <item> - <p>Read the <c>README</c> file in the installation directory for - last minute updates, before proceeding.</p> - </item> - <item> - <p>Run the <c>Install</c> script in the installation directory, - with the absolute path of the installation directory as argument,</p> - <pre> -./Install /usr/local/erlang/otp_r7b</pre> - <p>and supply answers to the prompts.</p> - <p>In most cases, there is a default answer in square brackets - (<c>[]</c>). If the default is satisfactory, just press - <c><![CDATA[<Return>]]></c>. In general you are only prompted for one thing:</p> - <list type="bulleted"> - <item> - <p>"Do you want to use a minimal system startup instead of the - SASL startup?" <br></br> - - In a minimal system, only the Kernel and STDLIB applications - are loaded and started. If the SASL startup is used, the SASL - application is included as well. Normally, the minimal system - is enough.</p> - </item> - </list> - </item> - <item> - <p>Make Erlang/OTP available for users, either by putting the path - <c>/usr/local/erlang/otp_r7b/bin</c> in users <c>$PATH</c> - variable, or link the executable - <c>/usr/local/erlang/otp_r7b/bin/erl</c> accordingly, e.g.:</p> - <pre> -ln -s /usr/local/erlang/otp_r7b/bin/erl /usr/local/bin/erl </pre> - </item> - </list> - </section> - </section> - <section> <title>Windows</title> <section> <title>Introduction</title> - <p>The system is delivered as a single <c>.exe</c> file.</p> - <p>To browse the on-line HTML documentation, Netscape or an equivalent - browser supporting frames is needed.</p> + <p>The system is delivered as a Windows Installer executable. + Get it from our <url href="http://www.erlang.org/download.html">download page</url>.</p> </section> <section> - <title>Installation Procedure</title> + <title>Installation</title> <p>The installation procedure is is automated. Double-click the <c>.exe</c> file icon and follow the instructions.</p> </section> + <section> + <title>Verification</title> + <list type="bulleted"> + <item> + <p>Start Erlang/OTP by double-clicking on the Erlang shortcut icon on the + desktop.</p> + <p>Expect a command line window to pop up with an output looking something like this:</p> + <pre> + Erlang/OTP 17 [erts-6.0] [64-bit] [smp:2:2] + + Eshell V6.0 (abort with ^G) + 1></pre> + </item> + <item> + <p>Exit by entering the command <c>halt()</c>,</p> + <pre> + 2> <input>halt().</input></pre> + <p>which will close the Erlang/OTP shell. </p> + </item> + </list> + </section> </section> </chapter> diff --git a/system/doc/installation_guide/otp_version.xml b/system/doc/installation_guide/otp_version.xml deleted file mode 100644 index 0ce5144160..0000000000 --- a/system/doc/installation_guide/otp_version.xml +++ /dev/null @@ -1,96 +0,0 @@ -<?xml version="1.0" encoding="utf-8" ?> -<!DOCTYPE chapter SYSTEM "chapter.dtd"> - -<chapter> - <header> - <copyright> - <year>2014</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. - - </legalnotice> - - <title>OTP version</title> - <prepared></prepared> - <responsible></responsible> - <docno></docno> - <approved></approved> - <checked></checked> - <date>2014-02-19</date> - <rev></rev> - <file>otp_version.xml</file> - </header> - <p>As of OTP release 17, the OTP release number corresponds to - the major part of the OTP version. The OTP version as a concept was - introduced in OTP 17. In the normal case, the OTP version will be - constructed as - <c><Major>.<Minor>.<Patch></c> where <c><Major></c> - is the most significant part. However, more dot separated parts than - this may exist. The dot separated parts consists of integers. If all - parts less significant than <c><Minor></c> equals <c>0</c>, they - are omitted. The three normal parts - <c><Major>.<Minor>.<Patch></c> will be changed as - follows:</p> - <taglist> - <tag><c><Major></c></tag><item>Increased when major changes, - including incompatibilities, have been made.</item> - <tag><c><Minor></c></tag><item>Increased when new functionality - has been added.</item> - <tag><c><Patch></c></tag><item>Increased when pure bug fixes - have been made.</item> - </taglist> - <p>When a part in the version number is increased, all less significant - parts are set to <c>0</c>. Release candidates have an <c>-rc<N></c> - suffix. The suffix <c>-rc0</c> will be used during development up to - the first release candidate.</p> - - <p>OTP of a specific version is a set of applications of - specific versions. The application versions identified by - an OTP version corresponds to application versions that - have been tested together by the Erlang/OTP team at Ericsson AB. - An OTP system can however be put together with applications from - different OTP versions. Such a combination of application versions - has not been tested by the Erlang/OTP team. It is therefore - <em>always preferred to use OTP applications from one single OTP - version</em>.</p> - - <p>Application versions will be managed the same way as the OTP version. - Application versions part of a release candidate will however not have an - <c>-rc<N></c> suffix as the OTP version. Also note that a major - increment in an application version does not necessarily imply a major - increment of the OTP version. This depends on whether the - major change in the application is considered as a major change for - OTP as a whole or not.</p> - - <p>In an OTP source code tree as well as in an installed OTP - development system, the OTP version can be read from the text - file <c>OTP_VERSION</c> in the OTP installation root directory - (<seealso marker="kernel:code#root_dir/0"><c>code:root_dir()</c></seealso>).</p> - <p>If the version read from the <c>OTP_VERSION</c> file in a - development system has a <c>**</c> suffix, the system has been - patched using the <c>$ERL_TOP/otp_build patch_app</c> tool. In - this case, the system consists of application versions from - multiple OTP versions. The version preceding the <c>**</c> - suffix corresponds to the OTP version of the base system that - has been patched. Note that if a development system is updated by - other means than <c>$ERL_TOP/otp_build patch_app</c>, the - <c>OTP_VERSION</c> file may identify wrong OTP version.</p> - - <p>On a target system (see the - <seealso marker="doc/system_principles:create_target">system principles</seealso> - documentation) no <c>OTP_VERSION</c> file will exist. This since - one easily can create a target system where it is hard to even - determine the base OTP version.</p> -</chapter> - diff --git a/system/doc/installation_guide/part.xml b/system/doc/installation_guide/part.xml index 150df39512..02bf98db7c 100644 --- a/system/doc/installation_guide/part.xml +++ b/system/doc/installation_guide/part.xml @@ -4,7 +4,7 @@ <part xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>2000</year><year>2013</year> + <year>2000</year><year>2014</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -31,11 +31,8 @@ <description> <p>How to install Erlang/OTP on UNIX or Windows.</p> </description> - <xi:include href="otp_version.xml"/> <xi:include href="install-binary.xml"/> - <xi:include href="verification.xml"/> <xi:include href="INSTALL.xml"/> <xi:include href="INSTALL-CROSS.xml"/> <xi:include href="INSTALL-WIN32.xml"/> - <xi:include href="MARKDOWN.xml"/> </part>
\ No newline at end of file diff --git a/system/doc/installation_guide/verification.xml b/system/doc/installation_guide/verification.xml deleted file mode 100644 index 391ddfb7b8..0000000000 --- a/system/doc/installation_guide/verification.xml +++ /dev/null @@ -1,102 +0,0 @@ -<?xml version="1.0" encoding="utf-8" ?> -<!DOCTYPE chapter SYSTEM "chapter.dtd"> - -<chapter> - <header> - <copyright> - <year>2000</year><year>2013</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. - - </legalnotice> - - <title>Installation Verification</title> - <prepared>Peter Högfeldt</prepared> - <responsible>Peter Högfeldt</responsible> - <docno></docno> - <approved>(Peter Högfeldt</approved> - <checked></checked> - <date>1997-05-26</date> - <rev>C</rev> - <file>verification.xml</file> - </header> - <p>This chapter is about verifying your installation by performing - a few simple tests to see that your system is properly installed.</p> - - <section> - <title>UNIX</title> - <list type="bulleted"> - <item> - <p>Start Erlang/OTP from the command line,</p> - <pre> - unix> erl</pre> - <p>Expect the following output:</p> - <pre> - Erlang (BEAM) emulator version 5.0.1 [threads] - - Eshell V5.0.1 (abort with ^G) - 1></pre> - </item> - <item> - <p>Start the GS-based toolbar from the Erlang shell, </p> - <pre> - 1> <input>toolbar:start().</input></pre> - <p>and check that the toolbar window pops up. - </p> - <p><em>Note:</em> The trailing full stop (<c>"."</c>) is an end marker - for all commands in the Erlang shell, and must be entered for a - command to begin execution.</p> - </item> - <item> - <p>Exit by entering the command <c>halt()</c>,</p> - <pre> - 2> <input>halt().</input></pre> - <p>which should end both the toolbar window and the command line window. </p> - </item> - </list> - </section> - - <section> - <title>Windows</title> - <list type="bulleted"> - <item> - <p>Start Erlang/OTP by double-clicking on the Erlang shortcut icon on the - desktop.</p> - <p>Expect a command line window to pop up with the following output,</p> - <pre> - Erlang (BEAM) emulator version 5.0.1 [threads] - - Eshell V5.0.1 (abort with ^G) - 1></pre> - </item> - <item> - <p>Start the GS-based toolbar from the Erlang shell, </p> - <pre> - 1> <input>toolbar:start().</input></pre> - <p>and check that the toolbar window pops up. - </p> - <p><em>Note:</em> The trailing full stop (<c>"."</c>) is an end marker - for all commands in the Erlang shell, and must be entered for a - command to begin execution.</p> - </item> - <item> - <p>Exit by entering the command <c>halt()</c>,</p> - <pre> - 2> <input>halt().</input></pre> - <p>which should end both the toolbar window and the command line window. </p> - </item> - </list> - </section> -</chapter> - diff --git a/system/doc/installation_guide/xmlfiles.mk b/system/doc/installation_guide/xmlfiles.mk index 245491ab94..c443334cd7 100644 --- a/system/doc/installation_guide/xmlfiles.mk +++ b/system/doc/installation_guide/xmlfiles.mk @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2009-2013. All Rights Reserved. +# Copyright Ericsson AB 2009-2014. 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 @@ -17,10 +17,7 @@ # %CopyrightEnd% # INST_GUIDE_CHAPTER_FILES = \ - otp_version.xml \ install-binary.xml \ - verification.xml \ INSTALL.xml \ INSTALL-CROSS.xml \ - INSTALL-WIN32.xml \ - MARKDOWN.xml + INSTALL-WIN32.xml diff --git a/system/doc/programming_examples/fun_test.erl b/system/doc/programming_examples/fun_test.erl index 8472fd87f8..8a3b0106c0 100644 --- a/system/doc/programming_examples/fun_test.erl +++ b/system/doc/programming_examples/fun_test.erl @@ -1,17 +1,11 @@ %1 -module(fun_test). --export([t1/0, t2/0, t3/0, t4/0, double/1]). +-export([t1/0, t2/0]). -import(lists, [map/2]). t1() -> map(fun(X) -> 2 * X end, [1,2,3,4,5]). t2() -> map(fun double/1, [1,2,3,4,5]). -t3() -> map({?MODULE, double}, [1,2,3,4,5]). - double(X) -> X * 2. %1 - - -t4() -> - "hello world". diff --git a/system/doc/reference_manual/character_set.xml b/system/doc/reference_manual/character_set.xml new file mode 100644 index 0000000000..b09b484582 --- /dev/null +++ b/system/doc/reference_manual/character_set.xml @@ -0,0 +1,133 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE chapter SYSTEM "chapter.dtd"> + +<chapter> + <header> + <copyright> + <year>2014</year><year>2014</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. + + </legalnotice> + + <title>Character Set and Source File Encoding</title> + <prepared></prepared> + <docno></docno> + <date></date> + <rev></rev> + <file>character_set.xml</file> + </header> + + <section> + <title>Character Set</title> + <p>In Erlang 4.8/OTP R5A the syntax of Erlang tokens was extended to + allow the use of the full ISO-8859-1 (Latin-1) character set. This + is noticeable in the following ways:</p> + <list type="bulleted"> + <item> + <p>All the Latin-1 printable characters can be used and are + shown without the escape backslash convention.</p> + </item> + <item> + <p>Atoms and variables can use all Latin-1 letters.</p> + </item> + </list> + <table> + <row> + <cell align="left" valign="middle"><em>Octal</em></cell> + <cell align="left" valign="middle"><em>Decimal</em></cell> + <cell align="left" valign="middle"> </cell> + <cell align="left" valign="middle"><em>Class</em></cell> + </row> + <row> + <cell align="left" valign="middle">200 - 237</cell> + <cell align="left" valign="middle">128 - 159</cell> + <cell align="left" valign="middle"> </cell> + <cell align="left" valign="middle">Control characters</cell> + </row> + <row> + <cell align="left" valign="middle">240 - 277</cell> + <cell align="left" valign="middle">160 - 191</cell> + <cell align="right" valign="middle">- ¿</cell> + <cell align="left" valign="middle">Punctuation characters</cell> + </row> + <row> + <cell align="left" valign="middle">300 - 326</cell> + <cell align="left" valign="middle">192 - 214</cell> + <cell align="center" valign="middle">À - Ö</cell> + <cell align="left" valign="middle">Uppercase letters</cell> + </row> + <row> + <cell align="center" valign="middle">327</cell> + <cell align="center" valign="middle">215</cell> + <cell align="center" valign="middle">×</cell> + <cell align="left" valign="middle">Punctuation character</cell> + </row> + <row> + <cell align="left" valign="middle">330 - 336</cell> + <cell align="left" valign="middle">216 - 222</cell> + <cell align="center" valign="middle">Ø - Þ</cell> + <cell align="left" valign="middle">Uppercase letters</cell> + </row> + <row> + <cell align="left" valign="middle">337 - 366</cell> + <cell align="left" valign="middle">223 - 246</cell> + <cell align="center" valign="middle">ß - ö</cell> + <cell align="left" valign="middle">Lowercase letters</cell> + </row> + <row> + <cell align="center" valign="middle">367</cell> + <cell align="center" valign="middle">247</cell> + <cell align="center" valign="middle">÷</cell> + <cell align="left" valign="middle">Punctuation character</cell> + </row> + <row> + <cell align="left" valign="middle">370 - 377</cell> + <cell align="left" valign="middle">248 - 255</cell> + <cell align="center" valign="middle">ø - ÿ</cell> + <cell align="left" valign="middle">Lowercase letters</cell> + </row> + <tcaption>Character Classes.</tcaption> + </table> + <p>In Erlang/OTP R16B the syntax of Erlang tokens was extended to + handle Unicode. The support is limited to + string literals and comments. Atoms, module names, and + function names are restricted to the ISO-Latin-1 range. + More about the usage of Unicode in Erlang source files + can be found in <seealso + marker="stdlib:unicode_usage#unicode_in_erlang">STDLIB's User's + Guide</seealso>.</p> + </section> + <section> + <title>Source File Encoding</title> + <p>The Erlang source file <marker + id="encoding">encoding</marker> is selected by a + comment in one of the first two lines of the source file. The + first string that matches the regular expression + <c>coding\s*[:=]\s*([-a-zA-Z0-9])+</c> selects the encoding. If + the matching string is not a valid encoding it is ignored. The + valid encodings are <c>Latin-1</c> and <c>UTF-8</c> where the + case of the characters can be chosen freely.</p> + <p>The following example selects UTF-8 as default encoding:</p> + <pre> +%% coding: utf-8</pre> + <p>Two more examples, both selecting Latin-1 as default encoding:</p> + <pre> +%% For this file we have chosen encoding = Latin-1</pre> + <pre> +%% -*- coding: latin-1 -*-</pre> + <p>The default encoding for Erlang source files was changed from + Latin-1 to UTF-8 in Erlang OTP 17.0.</p> + </section> +</chapter> diff --git a/system/doc/reference_manual/data_types.xml b/system/doc/reference_manual/data_types.xml index 8c690d6b86..37c0db5ff7 100644 --- a/system/doc/reference_manual/data_types.xml +++ b/system/doc/reference_manual/data_types.xml @@ -190,6 +190,38 @@ adam </section> <section> + <title>Map</title> + <p>Compound data type with a variable number of key-value associations:</p> + <pre> +#{Key1=>Value1,...,KeyN=>ValueN}</pre> + <p>Each key-value association in the map is called an + <em>association pair</em>. The key and value parts of the pair are + called <em>elements</em>. The number of association pairs is said to be + the <em>size</em> of the map.</p> + <p>There exists a number of BIFs to manipulate maps.</p> + <p>Examples:</p> + <pre> +1> <input>M1 = #{name=>adam,age=>24,date=>{july,29}}.</input> +#{age => 24,date => {july,29},name => adam} +2> <input>maps:get(name,M1).</input> +adam +3> <input>maps:get(date,M1).</input> +{july,29} +4> <input>M2 = maps:update(age,25,M1).</input> +#{age => 25,date => {july,29},name => adam} +5> <input>map_size(M).</input> +3 +6> <input>map_size(#{}).</input> +0</pre> + <p>A collection of maps processing functions can be found in + the STDLIB module <seealso marker="stdlib:maps"><c>maps</c></seealso>.</p> + <p>Read more about <seealso marker="expressions#map_expressions">Maps</seealso>.</p> + <note> + <p>Maps are considered experimental during OTP 17.</p> + </note> + </section> + + <section> <title>List</title> <p>Compound data type with a variable number of terms.</p> <pre> diff --git a/system/doc/reference_manual/expressions.xml b/system/doc/reference_manual/expressions.xml index e9de3e006e..62a344ad58 100644 --- a/system/doc/reference_manual/expressions.xml +++ b/system/doc/reference_manual/expressions.xml @@ -56,7 +56,7 @@ Expr1 + Expr2</code> <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> @@ -283,7 +283,7 @@ 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 @@ -301,7 +301,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 @@ -792,6 +792,245 @@ Expr1 -- Expr2</pre> </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 may 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 <c>,</c>. + </p> + + <p> + Examples: + </p> + <code> +M0 = #{}, % empty map +M1 = #{a => <<"hello">>}, % 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> + where, <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 will take precedence. + </p> + <p> + Example: + </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 above mentioned case of two matching keys. + </p> + </section> + + <section> + <title>Updating Maps</title> + <p> + Updating a map has 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> + where <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 + will be created from key <c>K</c> to value <c>V</c>. If key <c>K</c> matches + an existing key in map <c>M</c> its associated value will be replaced by the + new value <c>V</c>. In both cases the evaluated map expression will return 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> + where <c>M</c> is an term of type map, <c>V</c> is an expression and <c>K</c> + is an expression which 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> will be triggered at runtime. If a matching key <c>K</c> + is present in map <c>M</c> its associated value will be 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> + Examples: + </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> + where <c>M0</c> is any map. It follows that <c>M1 .. M4</c> are maps as well. + </p> + <p> + More Examples: + </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 which + case the latter value is used. + </p> + </section> + + <section> + <title>Maps in Patterns</title> + <p> + Matching of key-value associations from maps is done in the following way: + </p> + + <code>#{ K := V } = M</code> + <p> + where <c>M</c> is any map. The key <c>K</c> has to be an expression with bound + variables or a literals, and <c>V</c> can be any pattern with either bound or + unbound variables. + </p> + <p> + If the variable <c>V</c> is unbound, it will be bound to the value associated + with the key <c>K</c>, which has to exist in the map <c>M</c>. If the variable + <c>V</c> is bound, it has to match the value associated with <c>K</c> in <c>M</c>. + </p> + <p> Example: </p> +<code> +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.</code> + <p> + This will bind variable <c>B</c> to integer <c>2</c>. + </p> + <p> + Similarly, multiple values from the map may be matched: + </p> + <code>#{ K1 := V1, .., Kn := Vn } = M</code> + <p> + where 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> will be matched to the + associated values of their respective keys. + </p> + <p> + If the matching conditions are not met, the match will fail, either with + </p> + <list> + <item> + a <c>badmatch</c> exception, if used in the context of the matching operator + as in the example, + </item> + <item> + or resulting in the next clause being tested in function heads and + case expressions. + </item> + </list> + <p> + Matching in maps only allows for <c>:=</c> as delimiters of associations. + The order in which keys are declared in matching has no relevance. + </p> + <p> + Duplicate keys are allowed in matching and will match each pattern associated + to the keys. + </p> + <code>#{ K := V1, K := V2 } = M</code> + <p> + Matching an expression against an empty map literal will match its type but + no variables will be bound: + </p> + <code>#{} = Expr</code> + <p> + This expression will match if the expression <c>Expr</c> is of type map, otherwise + it will fail with an exception <c>badmatch</c>. + </p> + <section> + <title>Matching syntax: Example with literals in function heads</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 sub-expressions are valid guard expressions. + </p> + <p> + Two guard BIFs handles maps: + </p> + <list> + <item> + <seealso marker="erts:erlang#is_map/1">is_map/1</seealso> + </item> + <item> + <seealso marker="erts:erlang#map_size/1">map_size/1</seealso> + </item> + </list> + </section> + </section> + + <section> <marker id="bit_syntax"></marker> <title>Bit Syntax Expressions</title> <code type="none"><![CDATA[<<>> @@ -1348,6 +1587,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> @@ -1398,6 +1640,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> diff --git a/system/doc/reference_manual/introduction.xml b/system/doc/reference_manual/introduction.xml index aa42967625..36bec17825 100644 --- a/system/doc/reference_manual/introduction.xml +++ b/system/doc/reference_manual/introduction.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2003</year><year>2013</year> + <year>2003</year><year>2014</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -79,88 +79,5 @@ when xor</p> </section> - <section> - <title>Character Set</title> - <p>In Erlang 4.8/OTP R5A the syntax of Erlang tokens was extended to - allow the use of the full ISO-8859-1 (Latin-1) character set. This - is noticeable in the following ways:</p> - <list type="bulleted"> - <item> - <p>All the Latin-1 printable characters can be used and are - shown without the escape backslash convention.</p> - </item> - <item> - <p>Atoms and variables can use all Latin-1 letters.</p> - </item> - </list> - <table> - <row> - <cell align="left" valign="middle"><em>Octal</em></cell> - <cell align="left" valign="middle"><em>Decimal</em></cell> - <cell align="left" valign="middle"> </cell> - <cell align="left" valign="middle"><em>Class</em></cell> - </row> - <row> - <cell align="left" valign="middle">200 - 237</cell> - <cell align="left" valign="middle">128 - 159</cell> - <cell align="left" valign="middle"> </cell> - <cell align="left" valign="middle">Control characters</cell> - </row> - <row> - <cell align="left" valign="middle">240 - 277</cell> - <cell align="left" valign="middle">160 - 191</cell> - <cell align="right" valign="middle">- ¿</cell> - <cell align="left" valign="middle">Punctuation characters</cell> - </row> - <row> - <cell align="left" valign="middle">300 - 326</cell> - <cell align="left" valign="middle">192 - 214</cell> - <cell align="center" valign="middle">À - Ö</cell> - <cell align="left" valign="middle">Uppercase letters</cell> - </row> - <row> - <cell align="center" valign="middle">327</cell> - <cell align="center" valign="middle">215</cell> - <cell align="center" valign="middle">×</cell> - <cell align="left" valign="middle">Punctuation character</cell> - </row> - <row> - <cell align="left" valign="middle">330 - 336</cell> - <cell align="left" valign="middle">216 - 222</cell> - <cell align="center" valign="middle">Ø - Þ</cell> - <cell align="left" valign="middle">Uppercase letters</cell> - </row> - <row> - <cell align="left" valign="middle">337 - 366</cell> - <cell align="left" valign="middle">223 - 246</cell> - <cell align="center" valign="middle">ß - ö</cell> - <cell align="left" valign="middle">Lowercase letters</cell> - </row> - <row> - <cell align="center" valign="middle">367</cell> - <cell align="center" valign="middle">247</cell> - <cell align="center" valign="middle">÷</cell> - <cell align="left" valign="middle">Punctuation character</cell> - </row> - <row> - <cell align="left" valign="middle">370 - 377</cell> - <cell align="left" valign="middle">248 - 255</cell> - <cell align="center" valign="middle">ø - ÿ</cell> - <cell align="left" valign="middle">Lowercase letters</cell> - </row> - <tcaption>Character Classes.</tcaption> - </table> - <p>In Erlang/OTP R16 the syntax of Erlang tokens was extended to - handle Unicode. To begin with the support is limited to strings, - but Erlang/OTP R18 is expected to handle Unicode atoms as well. - More about the usage of Unicode in Erlang source files can be - found in <seealso - marker="stdlib:unicode_usage#unicode_in_erlang">STDLIB's User'S - Guide</seealso>. The default encoding for Erlang source files - is still Latin-1, but in Erlang/OTP R17 the default encoding - will be UTF-8. The details on how to state the encoding of an - Erlang source file can be found in <seealso - marker="stdlib:epp#encoding">epp(3)</seealso>.</p> - </section> </chapter> diff --git a/system/doc/reference_manual/modules.xml b/system/doc/reference_manual/modules.xml index 9e5f4de385..f0ec7ef165 100644 --- a/system/doc/reference_manual/modules.xml +++ b/system/doc/reference_manual/modules.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2003</year><year>2013</year> + <year>2003</year><year>2014</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -53,10 +53,10 @@ fact(0) -> % | <pre> -Tag(Value).</pre> <p><c>Tag</c> must be an atom, while <c>Value</c> must be a literal - term. As a convenience in user-defined attributes, the literal term - <c>Value</c> the syntax <c>Name/Arity</c> - (where <c>Name</c> is an atom and <c>Arity</c> a positive integer) - will be translated to <c>{Name,Arity}</c>.</p> + term. As a convenience in user-defined attributes, if the literal term + <c>Value</c> has the syntax <c>Name/Arity</c> + (where <c>Name</c> is an atom and <c>Arity</c> a positive integer), + the term <c>Name/Arity</c> will be translated to <c>{Name,Arity}</c>.</p> <p>Any module attribute can be specified. The attributes are stored in the compiled code and can be retrieved by calling @@ -134,8 +134,21 @@ fact(0) -> % | standard behaviours <c>gen_server</c>, <c>gen_fsm</c>, <c>gen_event</c> or <c>supervisor</c>.</p> <p>The spelling <c>behavior</c> is also accepted.</p> - <p>Read more about behaviours and callback modules in OTP Design - Principles.</p> + <p>The callback functions of the module can be specified either + directly by the exported function <c>behaviour_info/1</c>:</p> + <pre> +behaviour_info(callbacks) -> Callbacks.</pre> + <p>or by a <c>-callback</c> attribute for each callback + function:</p> + <pre> +-callback Name(Arguments) -> Result.</pre> + <p>where <c>Arguments</c> is a list of zero or more arguments. + The <c>-callback</c> attribute is to be preferred since the + extra type information can be used by tools to produce + documentation or find discrepancies.</p> + <p>Read more about behaviours and callback modules in + <seealso marker="doc/design_principles:spec_proc#behaviours"> + OTP Design Principles</seealso>.</p> </section> <section> diff --git a/system/doc/reference_manual/part.xml b/system/doc/reference_manual/part.xml index b4f114c268..ee8f3dd7eb 100644 --- a/system/doc/reference_manual/part.xml +++ b/system/doc/reference_manual/part.xml @@ -4,7 +4,7 @@ <part xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>2003</year><year>2013</year> + <year>2003</year><year>2014</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -28,6 +28,7 @@ <rev></rev> </header> <xi:include href="introduction.xml"/> + <xi:include href="character_set.xml"/> <xi:include href="data_types.xml"/> <xi:include href="patterns.xml"/> <xi:include href="modules.xml"/> diff --git a/system/doc/reference_manual/processes.xml b/system/doc/reference_manual/processes.xml index 20bab1eb48..95ae0672ec 100644 --- a/system/doc/reference_manual/processes.xml +++ b/system/doc/reference_manual/processes.xml @@ -114,8 +114,8 @@ spawn(Module, Name, Args) -> pid() <p>Two processes can be <em>linked</em> to each other. A link between two processes <c>Pid1</c> and <c>Pid2</c> is created by <c>Pid1</c> calling the BIF <c>link(Pid2)</c> (or vice versa). - There also exists a number a <c>spawn_link</c> BIFs, which spawns - and links to a process in one operation.</p> + There also exist a number of <c>spawn_link</c> BIFs, which spawn + and link to a process in one operation.</p> <p>Links are bidirectional and there can only be one link between two processes. Repeated calls to <c>link(Pid)</c> have no effect.</p> <p>A link can be removed by calling the BIF <c>unlink(Pid)</c>.</p> diff --git a/system/doc/reference_manual/typespec.xml b/system/doc/reference_manual/typespec.xml index 71aec732cf..e4aa2ceda6 100644 --- a/system/doc/reference_manual/typespec.xml +++ b/system/doc/reference_manual/typespec.xml @@ -100,9 +100,10 @@ | Fun | Integer | List + | Map | Tuple | Union - | UserDefined %% described in Section 6.3 + | UserDefined %% described in Section 7.3 Atom :: atom() | Erlang_Atom %% 'foo', 'bar', ... @@ -126,10 +127,17 @@ | nonempty_improper_list(Type1, Type2) %% Type1 and Type2 as above | nonempty_list(Type) %% Proper non-empty list + Map :: map() %% stands for a map of any size + | #{} %% stands for a map of any size + | #{PairList} + Tuple :: tuple() %% stands for a tuple of any size | {} | {TList} + PairList :: Type => Type + | Type => Type, PairList + TList :: Type | Type, TList @@ -209,6 +217,9 @@ <cell><c>iolist()</c></cell><cell><c>maybe_improper_list(byte() | binary() | iolist(), binary() | [])</c></cell> </row> <row> + <cell><c>function()</c></cell><cell><c>fun()</c></cell> + </row> + <row> <cell><c>module()</c></cell><cell><c>atom()</c></cell> </row> <row> @@ -275,6 +286,10 @@ Records have been extended to possibly contain type information. This is described in the sub-section <seealso marker="#typeinrecords">"Type information in record declarations"</seealso> below. </p> + <note> + <p>Map types, both <c>map()</c> and <c>#{ ... }</c>, are considered experimental during OTP 17.</p> + <p>No type information of maps pairs, only the containing map types, are used by Dialyzer in OTP 17.</p> + </note> </section> <section> diff --git a/system/doc/system_architecture_intro/sys_arch_intro.xml b/system/doc/system_architecture_intro/sys_arch_intro.xml index 62add510ca..3e88548861 100644 --- a/system/doc/system_architecture_intro/sys_arch_intro.xml +++ b/system/doc/system_architecture_intro/sys_arch_intro.xml @@ -150,7 +150,7 @@ <item>Chapter 8: "Operation and Management Principles" describes the model for operation and maintenance of sub-systems.</item> <item>Chapter 9: "Tutorial" gives an orientation of the different interoperability mechanism, which can be used when integrating an - Erlang program with a program written in an other programming language.</item> + Erlang program with a program written in another programming language.</item> </list> </section> diff --git a/system/doc/system_principles/create_target.xmlsrc b/system/doc/system_principles/create_target.xmlsrc index fbc935d708..a8ee2d1245 100644 --- a/system/doc/system_principles/create_target.xmlsrc +++ b/system/doc/system_principles/create_target.xmlsrc @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2002</year><year>2013</year> + <year>2002</year><year>2014</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -21,7 +21,7 @@ </legalnotice> - <title>Creating a First Target System</title> + <title>Creating and Upgrading a Target System</title> <prepared>Peter Högfeldt</prepared> <responsible></responsible> <docno></docno> @@ -71,26 +71,27 @@ </section> <section> + <marker id="create"/> <title>Creating a Target System</title> <p>It is assumed that you have a working Erlang/OTP system structured according to the OTP Design Principles.</p> - <p><em>Step 1.</em> First create a <c>.rel</c> file (see - <c>rel(4)</c>) that specifies the <c>erts</c> version - and lists all applications that should be included in the new - basic target system. An example is the following + <p><em>Step 1.</em> First create a <c>.rel</c> file (see <seealso + marker="sasl:rel">rel(4)</seealso>) that specifies the <c>erts</c> + version and lists all applications that should be included in the + new basic target system. An example is the following <c>mysystem.rel</c> file:</p> <code type="none"> %% mysystem.rel {release, {"MYSYSTEM", "FIRST"}, - {erts, "5.1"}, - [{kernel, "2.7"}, - {stdlib, "1.10"}, - {sasl, "1.9.3"}, - {pea, "1.0"}]}. </code> + {erts, "5.10.4"}, + [{kernel, "2.16.4"}, + {stdlib, "1.19.4"}, + {sasl, "2.3.4"}, + {pea, "1.0"}]}.</code> <p>The listed applications are not only original Erlang/OTP applications but possibly also new applications that you have - written yourself (here examplified by the application + written yourself (here exemplified by the application <c>pea</c>). </p> <p><em>Step 2.</em> From the directory where the <c>mysystem.rel</c> file reside, start the Erlang/OTP system:</p> @@ -116,13 +117,13 @@ os> <input>erl -pa /home/user/target_system/myapps/pea-1.0/ebin</input></pre> <c>systools:make_tar/2</c>. That file has the following contents:</p> <code type="none"> -erts-5.1/bin/ +erts-5.10.4/bin/ releases/FIRST/start.boot releases/FIRST/mysystem.rel releases/mysystem.rel -lib/kernel-2.7/ -lib/stdlib-1.10/ -lib/sasl-1.9.3/ +lib/kernel-2.16.4/ +lib/stdlib-1.19.4/ +lib/sasl-2.3.4/ lib/pea-1.0/ </code> <p>The file <c>releases/FIRST/start.boot</c> is a copy of our <c>mysystem.boot</c></p> @@ -142,16 +143,19 @@ lib/pea-1.0/ </code> <item>Creates the temporary directory <c>tmp</c> and extracts the tar file <c>mysystem.tar.gz</c> into that directory. </item> <item>Deletes the <c>erl</c> and <c>start</c> files from - <c>tmp/erts-5.1/bin</c>. These files will be created again from + <c>tmp/erts-5.10.4/bin</c>. These files will be created again from source when installing the release.</item> <item>Creates the directory <c>tmp/bin</c>.</item> <item>Copies the previously created file <c>plain.boot</c> to <c>tmp/bin/start.boot</c>.</item> <item>Copies the files <c>epmd</c>, <c>run_erl</c>, and - <c>to_erl</c> from the directory <c>tmp/erts-5.1/bin</c> to + <c>to_erl</c> from the directory <c>tmp/erts-5.10.4/bin</c> to the directory <c>tmp/bin</c>.</item> + <item>Creates the directory <c>tmp/log</c>, which will be used + if the system is started as embedded with the <c>bin/start</c> + script.</item> <item>Creates the file <c>tmp/releases/start_erl.data</c> with - the contents "5.1 FIRST". This file is to be passed as data + the contents "5.10.4 FIRST". This file is to be passed as data file to the <c>start_erl</c> script. </item> <item>Recreates the file <c>mysystem.tar.gz</c> from the directories @@ -171,11 +175,11 @@ lib/pea-1.0/ </code> <item>Extracts the tar file <c>mysystem.tar.gz</c> into the target directory <c>/usr/local/erl-target</c>.</item> <item>In the target directory reads the file <c>releases/start_erl.data</c> - in order to find the Erlang runtime system version ("5.1").</item> + in order to find the Erlang runtime system version ("5.10.4").</item> <item>Substitutes <c>%FINAL_ROOTDIR%</c> and <c>%EMU%</c> for <c>/usr/local/erl-target</c> and <c>beam</c>, respectively, in the files <c>erl.src</c>, <c>start.src</c>, and - <c>start_erl.src</c> of the target <c>erts-5.1/bin</c> + <c>start_erl.src</c> of the target <c>erts-5.10.4/bin</c> directory, and puts the resulting files <c>erl</c>, <c>start</c>, and <c>run_erl</c> in the target <c>bin</c> directory.</item> @@ -185,6 +189,7 @@ lib/pea-1.0/ </code> </section> <section> + <marker id="start"/> <title>Starting a Target System</title> <p>Now we have a target system that can be started in various ways.</p> <p>We start it as a <em>basic target system</em> by invoking</p> @@ -193,7 +198,7 @@ os> <input>/usr/local/erl-target/bin/erl</input></pre> <p>where only the <c>kernel</c> and <c>stdlib</c> applications are started, i.e. the system is started as an ordinary development system. There are only two files needed for all this to work: - <c>bin/erl</c> file (obtained from <c>erts-5.1/bin/erl.src</c>) + <c>bin/erl</c> file (obtained from <c>erts-5.10.4/bin/erl.src</c>) and the <c>bin/start.boot</c> file (a copy of <c>plain.boot</c>).</p> <p>We can also start a distributed system (requires <c>bin/epmd</c>).</p> <p>To start all applications specified in the original @@ -208,9 +213,10 @@ os> <input>/usr/local/erl-target/bin/erl -boot /usr/local/erl-target/releases/FI <c>bin/run_erl</c>, which in turn calls <c>bin/start_erl</c> (roughly, <c>start_erl</c> is an embedded variant of <c>erl</c>). </p> - <p>The shell script <c>start</c> is only an example. You should - edit it to suite your needs. Typically it is executed when the - UNIX system boots.</p> + <p>The shell script <c>start</c>, which is generated from + erts-5.10.4/bin/start.src during installation, is only an + example. You should edit it to suite your needs. Typically it is + executed when the UNIX system boots.</p> <p><c>run_erl</c> is a wrapper that provides logging of output from the run-time system to file. It also provides a simple mechanism for attaching to the Erlang shell (<c>to_erl</c>).</p> @@ -218,7 +224,7 @@ os> <input>/usr/local/erl-target/bin/erl -boot /usr/local/erl-target/releases/FI (<c>"/usr/local/erl-target"</c>), the releases directory (<c>"/usr/local/erl-target/releases"</c>), and the location of the <c>start_erl.data</c> file. It reads the run-time system - version (<c>"5.1"</c>) and release version (<c>"FIRST"</c>) from + version (<c>"5.10.4"</c>) and release version (<c>"FIRST"</c>) from the <c>start_erl.data</c> file, starts the run-time system of the version found, and provides <c>-boot</c> flag specifying the boot file of the release version found @@ -245,7 +251,7 @@ os> <input>/usr/local/erl-target/bin/erl -boot /usr/local/erl-target/releases/FI <c>target_system:create/1</c>. In fact, if you create, in the current directory, not only the <c>mysystem.rel</c> file, but also a <c>sys.config</c> file, that latter file will be tacitly - put in the apropriate directory.</p> + put in the appropriate directory.</p> </section> <section> @@ -258,6 +264,198 @@ os> <input>/usr/local/erl-target/bin/erl -boot /usr/local/erl-target/releases/FI </section> <section> + <title>Creating the Next Version</title> + + <p> + In this example the <c>pea</c> application has been changed, and + so are <c>erts</c>, <c>kernel</c>, <c>stdlib</c> and + <c>sasl</c>. + </p> + + <p> + <em>Step 1.</em> Create the <c>.rel</c> file: + </p> + <code type="none"> +%% mysystem2.rel +{release, + {"MYSYSTEM", "SECOND"}, + {erts, "6.0"}, + [{kernel, "3.0"}, + {stdlib, "2.0"}, + {sasl, "2.4"}, + {pea, "2.0"}]}.</code> + <p> + <em>Step 2.</em> Create the application upgrade file (see + <seealso marker="sasl:appup">appup(4)</seealso>) for <c>pea</c>, + for example: + </p> + <code type="none"> +%% pea.appup +{"2.0", + [{"1.0",[{load_module,pea_lib}]}], + [{"1.0",[{load_module,pea_lib}]}]}.</code> + <p> + <em>Step 3.</em> From the directory where the + <c>mysystem2.rel</c> file reside, start the Erlang/OTP system: + </p> + <pre> +os> <input>erl -pa /home/user/target_system/myapps/pea-2.0/ebin</input></pre> + <p>giving the path to the new version of <c>pea</c>. </p> + + <p> + <em>Step 4.</em> Create the release upgrade file (see <seealso + marker="sasl:relup">relup(4)</seealso>): + </p> + <pre> +1> <input>systools:make_relup("mysystem2",["mysystem"],["mysystem"],[{path,["/home/user/target_system/myapps/pea-1.0/ebin","/my/old/erlang/lib/*/ebin"]}]).</input></pre> + <p> + where <c>"mysystem"</c> is the base release and + <c>"mysystem2"</c> is the release to upgrade to. + </p> + <p> + Note that the <c>path</c> option is used for pointing out the + old version of all applications. (The new versions are already + in the code path - assuming of course that the erlang node on + which this is executed is running the correct version of + Erlang/OTP.) + </p> + <p> + <em>Step 5.</em> Create the new release: + </p> + <pre> +2> <input>target_system:create("mysystem2").</input></pre> + <p> + Given that the <c>relup</c> file generated in step 4 above is + now located in the current directory, it will automatically be + included in the release package. + </p> + </section> + + <section> + <title>Upgrading the Target System</title> + <p> + This part is done on the target node, and for this example we + want the node to be running as an embedded system with the + <c>-heart</c> option, allowing automatic restart of the + node. See <seealso marker="#start">Starting a Target + System</seealso> above for more information. + </p> + <p> + We add <c>-heart</c> to <c>bin/start</c>: + </p> + <code type="none"> +#!/bin/sh +ROOTDIR=/usr/local/erl-target/ + +if [ -z "$RELDIR" ] +then + RELDIR=$ROOTDIR/releases +fi + +START_ERL_DATA=${1:-$RELDIR/start_erl.data} + +$ROOTDIR/bin/run_erl -daemon /tmp/ $ROOTDIR/log "exec $ROOTDIR/bin/start_erl $ROOTDIR $RELDIR $START_ERL_DATA -heart</code> + <p> + And we use the simplest possible <c>sys.config</c>, which we + store in <c>releases/FIRST</c>: + </p> + <code type="none"> +%% sys.config +[].</code> + <p> + Finally, in order to prepare the upgrade, we need to put the new + release package in the <c>releases</c> directory of the first + target system: + </p> + <pre> +os> <input>cp mysystem2.tar.gz /usr/local/erl-target/releases</input></pre> + <p> + And assuming that the node has been started like this: + </p> + <pre> +os> <input>/usr/local/erl-target/bin/start</input></pre> + <p> + it can be accessed like this: + </p> + <pre> +os> <input>/usr/local/erl-target/bin/to_erl /tmp/erlang.pipe.1</input></pre> + <p> + Also note that logs can be found in + <c>/usr/local/erl-target/log</c>. This directory is specified as + an argument to <c>run_erl</c>in the start script listed above. + </p> + <p> + <em>Step 1.</em> Unpack the release: + </p> + <pre> +1> <input>{ok,Vsn} = release_handler:unpack_release("mysystem2").</input></pre> + <p> + <em>Step 2.</em> Install the release: + </p> + <pre> +2> <input>release_handler:install_release(Vsn).</input> +<output>{continue_after_restart,"FIRST",[]} +heart: Tue Apr 1 12:15:10 2014: Erlang has closed. +heart: Tue Apr 1 12:15:11 2014: Executed "/usr/local/erl-target/bin/start /usr/local/erl-target/releases/new_start_erl.data" -> 0. Terminating. +[End]</output></pre> + <p> + The above return value and output after the call to + <c>release_handler:install_release/1</c> means that the + <c>release_handler</c> has restarted the node by using + <c>heart</c>. This will always be done when the upgrade involves + a change of <c>erts</c>, <c>kernel</c>, <c>stdlib</c> or + <c>sasl</c>. See <seealso marker="upgrade">Upgrade when + Erlang/OTP has Changed</seealso> for more infomation about this. + </p> + <p> + The node will be accessible via a new pipe: + </p> + <pre> +os> <input>/usr/local/erl-target/bin/to_erl /tmp/erlang.pipe.2</input></pre> + <p> + Let's see which releases we have in our system: + </p> + <pre> +1> <input>release_handler:which_releases().</input> +<output>[{"MYSYSTEM","SECOND", + ["kernel-3.0","stdlib-2.0","sasl-2.4","pea-2.0"], + current}, + {"MYSYSTEM","FIRST", + ["kernel-2.16.4","stdlib-1.19.4","sasl-2.3.4","pea-1.0"], + permanent}]</output></pre> + <p> + Our new release, "SECOND", is now the current release, but we + can also see that our "FIRST" release is still permanent. This + means that if the node would be restarted at this point, it + would come up running the "FIRST" release again. + </p> + <p> + <em>Step 3.</em> Make the new release permanent: + </p> + <pre> +2> <input>release_handler:make_permanent("SECOND").</input></pre> + + <p> + Now look at the releases again: + </p> + + <pre> +3> <input>release_handler:which_releases().</input> +<output>[{"MYSYSTEM","SECOND", + ["kernel-3.0","stdlib-2.0","sasl-2.4","pea-2.0"], + permanent}, + {"MYSYSTEM","FIRST", + ["kernel-2.16.4","stdlib-1.19.4","sasl-2.3.4","pea-1.0"], + old}]</output></pre> + + <p> + Here we see that the new release version is <c>permanent</c>, so + it would be safe to restart the node. + </p> + + </section> + + <section> <title>Listing of target_system.erl</title> <p>This module can also be found in the <c>examples</c> directory of the <c>sasl</c> application.</p> diff --git a/system/doc/system_principles/part.xml b/system/doc/system_principles/part.xml index 915d5aca9b..d05c89fde8 100644 --- a/system/doc/system_principles/part.xml +++ b/system/doc/system_principles/part.xml @@ -4,7 +4,7 @@ <part xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>1997</year><year>2013</year> + <year>1997</year><year>2014</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -31,5 +31,6 @@ <xi:include href="system_principles.xml"/> <xi:include href="error_logging.xml"/> <xi:include href="create_target.xml"/> + <xi:include href="upgrade.xml"/> + <xi:include href="versions.xml"/> </part> - diff --git a/system/doc/system_principles/system_principles.xml b/system/doc/system_principles/system_principles.xml index 4f2202fdd1..79ed86cd9f 100644 --- a/system/doc/system_principles/system_principles.xml +++ b/system/doc/system_principles/system_principles.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>1996</year><year>2013</year> + <year>1996</year><year>2014</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -34,13 +34,12 @@ <p>An Erlang runtime system is started with the command <c>erl</c>:</p> <pre> % <input>erl</input> -Erlang (BEAM) emulator version 5.2.3.5 [hipe] [threads:0] +Erlang/OTP 17 [erts-6.0] [hipe] [smp:8:8] -Eshell V5.2.3.5 (abort with ^G) +Eshell V6.0 (abort with ^G) 1> </pre> <p><c>erl</c> understands a number of command line arguments, see - <c>erl(1)</c>. A number of them are also described in this - chapter.</p> + <c>erl(1)</c>. A number of them are also described in this chapter.</p> <p>Application programs can access the values of the command line arguments by calling one of the functions <c>init:get_argument(Key)</c>, or <c>init:get_arguments()</c>. @@ -110,7 +109,7 @@ init:stop()</pre> <p>Loads the code for and starts the applications Kernel and STDLIB, skips loading the <c>.erlang</c> file. Useful for scripts and other tools that should be behave the - same irregardless of user preferences. + same regardless of user preferences. </p> </item> </taglist> diff --git a/system/doc/system_principles/upgrade.xml b/system/doc/system_principles/upgrade.xml new file mode 100644 index 0000000000..68e48da0b8 --- /dev/null +++ b/system/doc/system_principles/upgrade.xml @@ -0,0 +1,118 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE chapter SYSTEM "chapter.dtd"> + +<chapter> + <header> + <copyright> + <year>2014</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. + + </legalnotice> + + <title>Upgrade when Erlang/OTP has Changed</title> + <prepared></prepared> + <responsible></responsible> + <docno></docno> + <approved></approved> + <checked></checked> + <date>2014-02-19</date> + <rev></rev> + <file>upgrade.xml</file> + </header> + + <section> + <title>Introduction</title> + <p> + As of Erlang/OTP 17, most applications deliver a valid + application upgrade (<c>appup</c>) file. In earlier releases, a + majority of the applications in Erlang/OTP did not support + upgrade at all. Many of the applications use the + <c>restart_application</c> instruction. These are applications + for which it is not crucial to support real soft upgrade, for + instance tools and library applications. The + <c>restart_application</c> instruction + ensures that all modules in the application are reloaded and + thereby running the new code. + </p> + </section> + + <section> + <title>Upgrade of core applications</title> + <p> + The core applications ERTS, Kernel, STDLIB + and SASL never allow real soft upgrade, but require the + Erlang emulator to be restarted. This is indicated to the + <c>release_handler</c> by the upgrade instruction + <c>restart_new_emulator</c>. This instruction will always be the + very first instruction executed, and it will restart the + emulator with the new versions of the above mentioned core + applications and the old versions of all other + applications. When the node is back up all other upgrade instructions are + executed, making sure each application is finally running its + new version. + </p> + + <p> + It might seem strange to do a two-step upgrade instead of + just restarting the emulator with the new version of all + applications. The reason for this design decision is to allow + <c>code_change</c> functions to have side effects, for example changing + data on disk. It also makes sure that the upgrade mechanism for + non-core applications does not differ depending on whether or not + core applications are changed at the same time. + </p> + + <p> + If, however, the more brutal variant is preferred, it is + possible to handwrite the release upgrade file using only the + single upgrade instruction <c>restart_emulator</c>. This + instruction, in contrast to <c>restart_new_emulator</c>, will + cause the emulator to restart with the new versions of + <em>all</em> applications. + </p> + + <p> + <em>Note</em> that if other instructions are included before + <c>restart_emulator</c> in the handwritten <c>relup</c> file, + they will be executed in the old emulator. This is a big risk + since there is no guarantee that new beam code can be loaded + into the old emulator. Adding instructions after + <c>restart_emulator</c> has no effect as the + <c>release_handler</c> will not do any attempt at executing + them. + </p> + + <p> + See <seealso marker="sasl:relup">relup(4)</seealso> for + information about the release upgrade file, and <seealso + marker="sasl:appup">appup(4)</seealso> for further information + about upgrade instructions. + </p> + </section> + + <section> + <title>Applications that still do not allow code upgrade</title> + <p> + A few applications, for instance HiPE do not support + upgrade at all. This is indicated by an application upgrade file + containing only <c>{Vsn,[],[]}</c>. Any attempt at creating a release + upgrade file with such input will fail. + The only way to force an upgrade involving applications like this is to + handwrite the <c>relup</c> file, preferably as described above + with only the <c>restart_emulator</c> instruction. + </p> + + </section> +</chapter> diff --git a/system/doc/system_principles/versions.xml b/system/doc/system_principles/versions.xml new file mode 100644 index 0000000000..ff042f4a3b --- /dev/null +++ b/system/doc/system_principles/versions.xml @@ -0,0 +1,267 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE chapter SYSTEM "chapter.dtd"> + +<chapter> + <header> + <copyright> + <year>2014</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. + + </legalnotice> + + <title>Versions</title> + <prepared></prepared> + <responsible></responsible> + <docno></docno> + <approved></approved> + <checked></checked> + <date>2014-02-19</date> + <rev></rev> + <file>versions.xml</file> + </header> + <section><title>OTP Version</title> + <p>As of OTP release 17, the OTP release number corresponds to + the major part of the OTP version. The OTP version as a concept was + introduced in OTP 17. The <seealso marker="#version_scheme">version + scheme</seealso> used is described in more detail below.</p> + + <p>OTP of a specific version is a set of applications of specific + versions. The application versions identified by an OTP version + corresponds to application versions that have been tested together + by the Erlang/OTP team at Ericsson AB. An OTP system can however be + put together with applications from different OTP versions. Such a + combination of application versions has not been tested by the + Erlang/OTP team. It is therefore <em>always preferred to use OTP + applications from one single OTP version</em>.</p> + + <p>Release candidates have an <c>-rc<N></c> + suffix. The suffix <c>-rc0</c> will be used during development up to + the first release candidate.</p> + + <section><title>Retrieving Current OTP Version</title> + <p>In an OTP source code tree, the OTP version can be read from + the text file <c><OTP source root>/OTP_VERSION</c>. The + absolute path to the file can be constructed by calling + <c>filename:join([<seealso marker="kernel:code#root_dir/0">code:root_dir()</seealso>, "OTP_VERSION"])</c>.</p> + <p>In an installed OTP development system, the OTP version can be read + from the text file <c><OTP installation root>/releases/<OTP release number>/OTP_VERSION</c>. + The absolute path to the file can by constructed by calling + <c>filename:join([<seealso marker="kernel:code#root_dir/0">code:root_dir()</seealso>, "releases", <seealso marker="erts:erlang#system_info_otp_release">erlang:system_info(otp_release)</seealso>, "OTP_VERSION"]).</c></p> + <p>If the version read from the <c>OTP_VERSION</c> file in a + development system has a <c>**</c> suffix, the system has been + patched using the <c>otp_patch_apply</c> tool available to + licensed customers. In this case, the system consists of application + versions from multiple OTP versions. The version preceding the <c>**</c> + suffix corresponds to the OTP version of the base system that + has been patched. Note that if a development system is updated by + other means than <c>otp_patch_apply</c>, the <c>OTP_VERSION</c> file + may identify an incorrect OTP version.</p> + + <p>No <c>OTP_VERSION</c> file will be placed in a + <seealso marker="create_target">target system</seealso> created + by OTP tools. This since one easily can create a target system + where it is hard to even determine the base OTP version. You may, + however, place such a file there yourself if you know the OTP + version.</p> + </section> + + <section><title>OTP Versions Table</title> + <p>The text file <c><OTP source root>/otp_versions.table</c> that + is part of the source code contains information about all OTP versions + from OTP 17.0 up to current OTP version. Each line contains information + about application versions that are part of a specific OTP version, and + is on the format:</p> +<pre> +<OtpVersion> : <ChangedAppVersions> # <UnchangedAppVersions> : +</pre> + <p><c><OtpVersion></c> is on the format <c>OTP-<VSN></c>, i.e., + the same as the git tag used to identify the source. + <c><ChangedAppVersions></c> and <c><UnchangedAppVersions></c> + are space separated lists of application versions on the + format <c><application>-<vsn></c>. + <c><ChangedAppVersions></c> corresponds to changed applications + with new version numbers in this OTP version, and + <c><UnchangedAppVersions></c> corresponds to unchanged application + versions in this OTP version. Both of them might be empty, although + not at the same time. If <ChangedAppVersions> is empty, no changes + has been made that change the build result of any application. This could + for example be a pure bug fix of the build system. The order of lines + is undefined. All white space characters in this file are either space + (character 32) or line-break (character 10).</p> + <p>Using ordinary UNIX tools like <c>sed</c> and <c>grep</c> one + can easily find answers to various questions like:</p> + <taglist> + <tag>Which OTP versions are <c>kernel-3.0</c> part of?</tag> + <item><p><c> $ grep ' kernel-3\.0 ' otp_versions.table</c></p></item> + <tag>In which OTP version was <c>kernel-3.0</c> introduced?</tag> + <item><p><c> $ sed 's/#.*//;/ kernel-3\.0 /!d' otp_versions.table</c></p></item> + </taglist> + <p>The above commands give a bit more information than the exact answers, + but adequate information when manually searching for answers to these + questions.</p> + <warning><p>The format of the <c>otp_versions.table</c> might be subject + to changes during the OTP 17 release.</p></warning> + </section> + </section> + + <section><title>Application Version</title> + <p>As of OTP 17.0 application versions will use the same + <seealso marker="#version_scheme">version scheme</seealso> as the + OTP version. Application versions part of a release candidate will + however not have an <c>-rc<N></c> suffix as the OTP version. + Also note that a major increment in an application version does not + necessarily imply a major increment of the OTP version. This depends + on whether the major change in the application is considered as a + major change for OTP as a whole or not.</p> + </section> + + <marker id="version_scheme"/> + <section><title>Version Scheme</title> + <note>Note that the version scheme was changed as of OTP 17.0. This implies + that application versions used prior to OTP 17.0 do not adhere to this + version scheme. <seealso marker="#otp_17_0_app_versions">A list of + application versions used in OTP 17.0</seealso> can be found + at the end of this document.</note> + + <p>In the normal case, a version will be constructed as + <c><Major>.<Minor>.<Patch></c> where <c><Major></c> + is the most significant part. However, more dot separated parts than + this may exist. The dot separated parts consists of non-negative integers. + If all parts less significant than <c><Minor></c> equals <c>0</c>, + they are omitted. The three normal parts + <c><Major>.<Minor>.<Patch></c> will be changed as + follows:</p> + <taglist> + <tag><c><Major></c></tag><item>Increased when major changes, + including incompatibilities, have been made.</item> + <tag><c><Minor></c></tag><item>Increased when new functionality + has been added.</item> + <tag><c><Patch></c></tag><item>Increased when pure bug fixes + have been made.</item> + </taglist> + <p>When a part in the version number is increased, all less significant + parts are set to <c>0</c>.</p> + + <p>An application version or an OTP version identifies source code + versions. That is, it does not imply anything about how the application + or OTP has been built.</p> + + <section><title>Order of Versions</title> + <p>Version numbers in general are only partially ordered. However, + normal version numbers (with three parts) as of OTP 17.0 have a total + or linear order. This applies both to normal OTP versions and + normal application versions.</p> + + <p>When comparing two version numbers that have an order, one + compare each part as ordinary integers from the most + significant part towards less significant parts. The order is + defined by the first parts of the same significance that + differ. An OTP version with a larger version include all + changes that that are part of a smaller OTP version. The same + goes for application versions.</p> + + <p>In the general case, versions may have more than three parts. In + this case the versions are only partially ordered. Note that such + versions are only used in exceptional cases. When an extra + part (out of the normal three parts) is added to a version number, + a new branch of versions is made. The new branch has a linear + order against the base version. However, versions on different + branches have no order. Since they have no order, we + only know that they all include what is included in their + closest common ancestor. When branching multiple times from the + same base version, <c>0</c> parts are added between the base + version and the least significant <c>1</c> part until a unique + version is found. Versions that have an order can be compared + as described in the paragraph above.</p> + + <p>An example of branched versions: The version <c>6.0.2.1</c> + is a branched version from the base version <c>6.0.2</c>. + Versions on the form <c>6.0.2.<X></c> can be compared + with normal versions smaller than or equal to <c>6.0.2</c>, + and other versions on the form <c>6.0.2.<X></c>. The + version <c>6.0.2.1</c> will include all changes in + <c>6.0.2</c>. However, <c>6.0.3</c> will most likely + <em>not</em> include all changes in <c>6.0.2.1</c> (note that + these versions have no order). A second branched version from the base + version <c>6.0.2</c> will be version <c>6.0.2.0.1</c>, and a + third branched version will be <c>6.0.2.0.0.1</c>.</p> + </section> + </section> + + <marker id="otp_17_0_app_versions"/> + <section><title>OTP 17.0 Application Versions</title> + <p>The following application versions were part of OTP 17.0. If + the normal part of an applications version number compares + as smaller than the corresponding application version in this list, + the version number does not adhere to the version scheme introduced + in OTP 17.0 and should be considered as not having an order against + versions used as of OTP 17.0.</p> + <list> + <item><c>asn1-3.0</c></item> + <item><c>common_test-1.8</c></item> + <item><c>compiler-5.0</c></item> + <item><c>cosEvent-2.1.15</c></item> + <item><c>cosEventDomain-1.1.14</c></item> + <item><c>cosFileTransfer-1.1.16</c></item> + <item><c>cosNotification-1.1.21</c></item> + <item><c>cosProperty-1.1.17</c></item> + <item><c>cosTime-1.1.14</c></item> + <item><c>cosTransactions-1.2.14</c></item> + <item><c>crypto-3.3</c></item> + <item><c>debugger-4.0</c></item> + <item><c>dialyzer-2.7</c></item> + <item><c>diameter-1.6</c></item> + <item><c>edoc-0.7.13</c></item> + <item><c>eldap-1.0.3</c></item> + <item><c>erl_docgen-0.3.5</c></item> + <item><c>erl_interface-3.7.16</c></item> + <item><c>erts-6.0</c></item> + <item><c>et-1.5</c></item> + <item><c>eunit-2.2.7</c></item> + <item><c>gs-1.5.16</c></item> + <item><c>hipe-3.10.3</c></item> + <item><c>ic-4.3.5</c></item> + <item><c>inets-5.10</c></item> + <item><c>jinterface-1.5.9</c></item> + <item><c>kernel-3.0</c></item> + <item><c>megaco-3.17.1</c></item> + <item><c>mnesia-4.12</c></item> + <item><c>observer-2.0</c></item> + <item><c>odbc-2.10.20</c></item> + <item><c>orber-3.6.27</c></item> + <item><c>os_mon-2.2.15</c></item> + <item><c>ose-1.0</c></item> + <item><c>otp_mibs-1.0.9</c></item> + <item><c>parsetools-2.0.11</c></item> + <item><c>percept-0.8.9</c></item> + <item><c>public_key-0.22</c></item> + <item><c>reltool-0.6.5</c></item> + <item><c>runtime_tools-1.8.14</c></item> + <item><c>sasl-2.4</c></item> + <item><c>snmp-4.25.1</c></item> + <item><c>ssh-3.0.1</c></item> + <item><c>ssl-5.3.4</c></item> + <item><c>stdlib-2.0</c></item> + <item><c>syntax_tools-1.6.14</c></item> + <item><c>test_server-3.7</c></item> + <item><c>tools-2.6.14</c></item> + <item><c>typer-0.9.6</c></item> + <item><c>webtool-0.8.10</c></item> + <item><c>wx-1.2</c></item> + <item><c>xmerl-1.3.7</c></item> + </list> + </section> +</chapter> + diff --git a/system/doc/system_principles/xmlfiles.mk b/system/doc/system_principles/xmlfiles.mk index 4cbc00ed52..c60ffbad28 100644 --- a/system/doc/system_principles/xmlfiles.mk +++ b/system/doc/system_principles/xmlfiles.mk @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2009. All Rights Reserved. +# Copyright Ericsson AB 2009-2014. 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 @@ -19,4 +19,6 @@ SYSTEM_PRINCIPLES_CHAPTER_FILES = \ system_principles.xml \ error_logging.xml \ - create_target.xml + create_target.xml \ + upgrade.xml \ + versions.xml diff --git a/system/doc/tutorial/c_portdriver.xmlsrc b/system/doc/tutorial/c_portdriver.xmlsrc index 421ea63f33..2fd6fb0aac 100644 --- a/system/doc/tutorial/c_portdriver.xmlsrc +++ b/system/doc/tutorial/c_portdriver.xmlsrc @@ -35,7 +35,7 @@ <section> <title>Port Drivers</title> - <p>A port driver is a linked in driver, that is accessible as a + <p>A port driver is a linked in driver that is accessible as a port from an Erlang program. It is a shared library (SO in Unix, DLL in Windows), with special entry points. The Erlang runtime calls these entry points, when the driver is started and when |