Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

First commit after move to GIThub

  • Loading branch information...
commit 30e4276dbe0d68c8a7aa893c302b1369bce1c443 0 parents
@matthiasl matthiasl authored
43 Makefile
@@ -0,0 +1,43 @@
+sources= \
+ introduction.xml \
+ faq_questions.xml \
+ obtaining.xml \
+ getting_started.xml \
+ how_do_i.xml \
+ libraries.xml \
+ tools.xml \
+ implementations.xml \
+ problems.xml \
+ academic.xml \
+ mnesia.xml
+
+# Erlang compiler
+ERL=12erl
+
+all: obj obj/faq.html obj/t1.html
+
+# Make a list of links in the document. I check these manually because
+# an automatic checker is likely to miss semi-dead pages.
+linkcheck: $(sources)
+ grep http $(sources) | cut -d \" -f 2 | sort | uniq > /home/matthias/links
+
+
+obj:
+ mkdir obj
+
+obj/faq.html: $(sources) make_faq.beam
+ $(ERL) -s make_faq go -s init stop
+
+# Historically, the FAQ started at t1.html. Preserve that to avoid breaking
+# people's links.
+obj/t1.html:
+ cp obj/faq_frame.html obj/t1.html
+
+%.beam: %.erl
+ $(ERL) -make
+
+ship:
+ (cd ..; tar -czvf ~/erlfaq.tgz faq/*.xml faq/Makefile faq/*erl faq/README faq/Makefile faq/erlang_magic_file)
+
+clean:
+ rm -rf obj/*
20 README
@@ -0,0 +1,20 @@
+Author: Matthias Lang
+Title: How to build the Erlang FAQ.
+----------------------------------------------------------------------
+
+Building the FAQ:
+ 1. Install Erlang R12B-1 or later
+ 2. make
+
+Installing at Erlang.org:
+
+ Since I don't have access to erlang.org, I ask Kent to install
+ it for me by sending him the tarfile and saying:
+
+ Here's how I used to update it:
+
+ cd /home/super/erlang/www/erlang.org/public/faq
+ rm x*.html
+ gunzip -c <whatever_the_tarfile_is> | tar -xvf -
+ (and then check, update the site)
+
814 academic.xml
@@ -0,0 +1,814 @@
+<?xml version="1.0" encoding="iso-8859-1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+<chapter>
+ <header>
+ <title>Academic and Historical Questions</title>
+ <prepared>Matthias Lang</prepared>
+<docno></docno>
+<date>2009-04-19</date>
+ <rev>1.1</rev>
+ </header>
+
+<section><title> Why is Erlang called "Erlang"?</title>
+<p>
+
+ Erlang is named after the mathematician Agner Erlang. Among other
+ things, he worked on queueing theory. The original implementors
+ also tend to avoid denying that Erlang sounds a little like
+ "ERicsson LANGuage".
+
+</p></section>
+<section><title>Who invented Erlang?</title>
+<p>
+ During the 1980s there was a project at the Ericsson
+ <url href="http://www.cs-lab.org/">
+ Computer Science Laboratory</url>
+ which aimed to find out what aspects of computer languages
+ made it easier to program telecommunications systems. Erlang
+ emerged in the second half of the 80s was the result of
+ taking those features which made writing such systems
+ simpler and avoiding those which made them more complex
+ or error prone.
+ </p><p>
+
+ The people involved at the start were Joe Armstrong,
+ Robert Virding and Mike Williams. Others joined later
+ and added things like distribution and OTP.
+
+</p></section>
+<section><title>Where does Erlang syntax come from?</title>
+<p>
+
+ Mostly from prolog. Erlang started life as a modified prolog.
+ ! as the send-message operator comes from CSP. Eripascal
+ was probably responsible for , and ; being separators and
+ not terminators.
+
+</p></section>
+<section><title>Why is Ericsson giving away Erlang?</title>
+<p>
+ (The following is my personal impression. I don't speak
+ for Ericsson!)
+ </p><p>
+
+ <em>Nothing to lose</em>: Ericsson's core business is
+ telecommunications products, selling programming
+ tools is not really a business Ericsson is interested in.
+ </p><p>
+
+ <em>Stimulate adoption</em>: Erlang is a great
+ language for many sorts of systems. Releasing a
+ good, free development environment is likely to
+ make Erlang catch on faster.
+ </p><p>
+
+ <em>Generate goodwill</em>: Giving away cool software can
+ only improve Ericsson's image, especially given the
+ current level of media attention around "open software".
+ </p><p>
+
+</p></section>
+<section><title>What can I do for Open Source Erlang?</title>
+<p>
+
+ Implement useful systems using Erlang. Spread the word!
+ </p><p>
+
+ Erlang is the easiest way to write fault-tolerant realtime software,
+ but people won't use it if they don't know about it.
+ </p><p>
+
+ The more people we have using Erlang, the better quality
+ the product becomes, the more cool applications we get
+ and the more libraries are added to Erlang. Volunteers have
+ already fixed several important bugs, created a
+ <url href="http://www.debian.org/">Debian GNU/Linux</url>
+ package and ported Erlang to new platforms.
+ </p><p>
+
+</p></section>
+
+<section><marker id="soft-realtime"/>
+<title>What does soft realtime mean?</title>
+<p>
+
+ Cynics will say "basically nothing".
+ </p><p>
+
+ A <em>hard realtime</em>
+ system is one which can guarantee that a certain action will
+ always be carried out in less than a certain time. Many simple
+ embedded systems can make hard realtime guarantees, e.g.
+ it is possible to guarantee that a particular interrupt
+ service routine on a Z80 CPU will never take more than
+ 34us. It gets progressively harder to make such guarantees for
+ more complex systems.
+ </p><p>
+
+ Many telecomms systems have less strict requirements, for
+ instance they might require a statistical guarantee
+ along the lines of "a database lookup takes less than 20ms
+ in 97% of cases". Soft realtime
+ systems, such as Erlang, let you make that sort of guarantee.
+
+ </p><p>
+ A rule of thumb is that it is straightforward to write
+ Erlang programs which can respond to
+ external events within a few milliseconds.
+ The parts of Erlang which help with this are:
+ </p>
+
+ <list>
+ <item><p>Language features which make it hard(er)
+ for programmers to roughly estimate performance were
+ never added to Erlang.
+ For instance, Erlang doesn't have lazy evaluation.
+ </p></item>
+
+ <item><p>Erlang processes are very lightweight, much lighter
+ than an operating system thread. Switching
+ between Erlang processes is typically an order
+ of magnitude or two faster than switching between
+ OS threads.
+ </p></item>
+
+ <item><p>Each Erlang process is garbage collected separately.
+ This avoids the (relatively) long delay which would
+ occur if there was a single large heap for all
+ processes.
+ </p></item>
+
+ </list>
+
+</section>
+<section><title> How did the first Erlang compiler get written?</title>
+<p>
+
+ (or: <em>how was Erlang bootstrapped?</em>) In Joe's words:
+</p>
+ <quote>
+ <p>
+ First I designed an abstract machine to execute Erlang.
+ This was called the JAM machine; JAM = Joe's
+ Abstract Machine.
+ </p>
+ </quote>
+
+ <quote>
+ <p>
+ Then I wrote a compiler from Erlang to JAM
+ and an emulator to see if the machine worked.
+ Both these were written in prolog.
+ </p>
+ </quote>
+
+ <quote>
+ <p>
+ At the same time Mike Williams wrote a C emulator for the JAM.
+ </p>
+ </quote>
+
+ <quote>
+ <p>
+ Then I rewrote the erlang-to-jam compiler in Erlang and
+ used the prolog compiler to compile it. The resultant
+ object code was run in the C emulator. Then we threw away prolog.
+ </p>
+ </quote>
+<p>
+ Some of this is described in <url
+ href="http://www.erlang.se/publications/prac_appl_prolog.ps">
+ an old paper</url>
+
+</p></section>
+<section><title> Erlang Syntax and Semantics Details</title>
+<p>
+
+ When in doubt about exactly what the language allows or does,
+ the best place to start is the
+ <url href="http://www.erlang.org/download/erl_spec47.ps.gz">
+ Erlang Specification</url>. This is still a work
+ in progress, but it covers most of the language.
+
+</p></section>
+<section><title> Is the order of message reception guaranteed?</title>
+<p>
+
+ Yes, but only within one process.
+ </p><p>
+ If there is a live process and you send it message A and then
+ message B, it's guaranteed that if message B arrived, message
+ A arrived before it.
+ </p><p>
+
+ On the other hand, imagine processes P, Q and R. P sends
+ message A to Q, and then message B to R. There is no
+ guarantee that A arrives before B. (Distributed Erlang would
+ have a pretty tough time if this was required!)
+</p>
+
+</section>
+<section><title>If I send a message, is it guaranteed to reach the receiver?
+</title>
+<p>
+
+ Most people find it simplest to program as though the answer
+ was <em>"yes, always"</em>.
+ </p><p>
+
+ Per Hedeland covered the issues on the mailing list (edited a bit):
+</p>
+
+ <quote>
+ <p>
+ "Delivery is guaranteed if nothing breaks" - and if something
+ breaks, you will find
+ out provided you've used <c>link/1</c>. I.e.
+ you will get an <c>EXIT</c> signal
+ not only if the linked process dies, but
+ also if the entire remote node crashes, or the network is
+ broken, or if any of these happen <em>before</em>
+ you do the link.
+ </p><p>
+
+ It seems this issue of "guaranteed delivery" comes up every
+ now and then, but I've never managed to find out exactly what
+ it is those that are asking for it actually want:
+ </p>
+ </quote>
+
+ <list>
+ <item><p>
+ A guarantee that the message is put into the receiver's
+ input queue? But if the receiver dies before extracting
+ it from there, that guarantee is useless, as the message
+ is lost anyway.
+ </p></item>
+
+ <item><p> A guarantee that the receiver extracts the message from its
+ input queue? Well, besides the obvious problem that
+ depending on how the receiver is written, even if
+ it lives happily ever after it may <em>never
+ </em> extract
+ that particular message, it suffers from a variant of
+ the previous problem: Even if you "know" that the
+ receiver has "consumed" the message, it may die before
+ acting on it in any way, and then again it may as well
+ never have been sent.
+ </p></item>
+
+ <item><p> A guarantee that the receiver actually
+ <em>processes</em>
+ the message? Just kidding of course, hopefully it's
+ obvious to everyone that the only way to obtain such
+ a guarantee, regardless of what programming and
+ communication system you use, is that the receiver
+ is programmed to send an explicit acknowledgment
+ when the processing is complete (of course this may
+ be hidden below an abstraction such as RPC, but the
+ fundamental principle holds).
+ </p></item>
+ </list>
+
+ <quote>
+ <p>
+ Add to this that any guarantee would <em>have</em>
+ to entail some
+ form of ack from the remote in at least a distributed
+ system, even if it wasn't directly visible to the
+ programmer. E.g. you could have '!' block until the ack
+ comes back from the remote saying that the message had
+ progressed however far you required - i.e. synchronous
+ communication of sorts. But this would penalize those that
+ <em>don't</em> require the "guarantee" and
+ <em>want</em> asynchronous communication.
+ </p><p>
+
+ So, depending on your requirements, Erlang offers you
+ <em>at least</em> these levels of "guarantee":
+ </p>
+ </quote>
+
+ <section>
+ <title>Super-safe</title>
+ <p>
+
+ Receiver sends ack after processing;
+ sender links, sends, waits for <c>ack</c>
+ or <c>EXIT</c>.
+ This means the sender knows, for each message, whether
+ it was fully processed or not.
+ </p>
+ </section>
+
+ <section>
+ <title>Medium-safe</title>
+ <p>
+ Receiver doesn't send acks; Sender links,
+ sends message(s). This means an <c>EXIT</c>
+ signal informs the sender that some messages may never have
+ been processed.
+ </p>
+ </section>
+
+ <section>
+ <title>Pretty-safe</title>
+ <p>
+ Receiver doesn't send acks; sender sends messages. :-)
+ </p>
+ </section>
+
+ <quote>
+ <p>
+ There are any number of combinations of these (e.g. receiver sends
+ ack not after each message but at some critical points in the
+ processing).
+ </p>
+ </quote>
+
+<p>
+ Per concluded by pointing out that "if you think TCP guarantees
+ delivery, which most people probably do, then so does Erlang".
+
+</p></section>
+<section><title> What limits does Erlang have?</title>
+<p>
+
+ The Erlang language doesn't specify any limits, but
+ different implementations have different limits on the
+ number of processes, the maximum amount of RAM and so on.
+ These are
+ <url href="http://erlang.org/doc/efficiency_guide/advanced.html#7.2">documented for each implementation</url>.
+
+</p></section>
+<section><title>Do funs behave during a code change?</title>
+<p>
+ Yes and no. A fun is a reference to code; it is not the
+ code itself. Thus a fun can only be evaluated if the code
+ it refers to is actually loaded on the evaluating node.
+
+ In some cases, we can be sure that execution will never
+ return to a fun. In these cases the old code can be purged
+ without problems. The following code causes no surprises:
+</p>
+
+ <code><![CDATA[
+ Parent = self(),
+ F = fun() -> loop(Parent) end,
+ spawn(F).
+ ]]></code>
+
+<p>
+ On the other hand, a bound fun will not be replaced.
+ In the following example, the old verson of F is
+ executed even after a code change:
+</p>
+
+<code><![CDATA[
+ -module(cc).
+ -export([go/0, loop/1]).
+
+ go() ->
+ F = fun() -> 5 end,
+ spawn(fun() -> loop(F) end).
+
+ loop(F) ->
+ timer:sleep(1000),
+ F(),
+ cc:loop(F).
+]]></code>
+
+<p>
+ This type of problem can be solved in the
+ <c>code_change/2</c> function in the standard behaviours.
+
+</p></section>
+<section><title>Examples of bound funs causing surprises</title>
+<p>
+ Some typical ways to get in trouble are:
+</p>
+
+ <list>
+ <item><p>Mnesia. If you store funs in mnesia, you need to
+ have a way to update the table (i.e. replace the
+ fun references) when you load code.</p></item>
+
+ <item><p>Serialisation. The same deal. If you serialise a
+ fun (e.g. <c>term_to_binary/1</c>) and
+ then unserialise it, you can only evaluate the fun
+ if the code it refers to still exists. In general,
+ serialising a fun, saving it to a file and then
+ loading it in another emulator will not do what you
+ hoped.</p></item>
+
+ <item><p>Message passing. Sending a fun to a remote node
+ always works, but the fun can only be evaluated on
+ a node where the same version of the same module is
+ available.</p></item>
+ </list>
+<p>
+ A general way to avoid problems with funs which refer to code
+ which doesn't exist is to store the function by name instead
+ of by reference, e.g. by writing <c>fun M:F/A</c>.
+
+</p></section>
+<section><title>Is it just me, or are records ugly?</title>
+<p>
+ Compared to the rest of Erlang, records are rather
+ ugly and error prone. They're ugly because they
+ require an awful lot of typing (no pun intended).
+ They're error prone because the usual method of defining
+ records, the <c>-include</c> directive,
+ provides no protection against multiple, incompatible
+ definitions of records.
+ </p><p>
+
+ Several ways forward have been explored. One is lisp-like
+ <em>structs</em> which have been discussed
+ on <url href="http://www.erlang.org/ml-archive/erlang-questions/200301/msg00103.html">the mailing list.</url>
+
+ Another is
+ Richard O'Keefe's <em>abstract patterns</em> which
+ was <url href="http://www.erlang.org/ml-archive/erlang-questions/200309/msg00309.html">also posted</url>.
+
+ Then there is also a suggestion for <url href="http://www.erlang.org/ml-archive/erlang-questions/200509/msg00329.html">making records more reliable</url>.
+
+</p></section>
+
+<section>
+ <marker id="priority-receive"/>
+ <title>Can a process receive messages with varying priorities?</title>
+<p>
+
+
+ Sure. Here's an example of how to do it using nested receives:
+</p>
+
+ <code><![CDATA[
+ receive ->
+ {priority_msg, Data1} -> priority(Data1)
+ after
+ 0 ->
+ receive
+ {priority_msg, Data1} -> priority(Data1)
+ {normal_msg, Data2} -> normal(Data2)
+ end
+ end.
+ ]]></code>
+
+
+</section>
+<section><title>Flamewars</title>
+<p>
+
+ The following "questions" all relate to topics which have
+ generated long discussions in public forums, often with
+ some amount of stepping on people's toes. If you're going
+ to post a news article (or write a report, or...) about any
+ of these, reading the answers here might help you avoid
+ some arguments we've already been through.
+
+</p></section>
+<section><title>What's the history of static type checking in Erlang?</title>
+<p>
+ Current versions of Erlang (R12B onwards) ship with a static
+ type analysis system called
+ the <url href="http://www.it.uu.se/research/group/hipe/dialyzer/">Dialyzer</url>. Using
+ the dialyzer is optional, though many or most serious projects
+ use it. The Dialyzer does not require source code to be
+ modified or annotated, though annotations increase the number
+ of problems the Dialyzer can find.
+</p>
+<p>
+ Until about 2005, static type checking was used rarely in
+ commercial Erlang-based systems. Several people experimented
+ with various approaches to the problem, including Sven-Olof
+ Nyström, Joe Armstrong, Philip Wadler, Simon Marlow and
+ Thomas Arts.
+</p>
+</section>
+
+<!-- This section is inspired by a post by ROK 23-Oct-2008 -->
+<section><title>How does type checking in Erlang compare to
+Java/Python/C/C++/Haskell?</title>
+<p>
+ Erlang itself, i.e. <em>ignoring</em> the Dialyzer, uses a
+ dynamic type system. All type checking is done
+ at run-time, the compiler does not check types at compile
+ time. The run-time type system cannot be defeated. This is
+ comparable to the type systems in Lisp, Smalltalk, Python,
+ Javascript, Prolog and others.
+</p>
+<p>
+ Java, Eiffel and some other languages have type systems which
+ are mostly checked at compile time, but with some remaining
+ checking done at run time. The combination of checking cannot
+ be defeated. Such type systems provide some guarantees about
+ types which can be exploited by the compiler, this can be
+ useful for optimisation.
+</p>
+<p>
+ Haskell, Mercury and some other languages have type systems
+ which are completely checked at compile time. This type system
+ cannot be defeated. The type system in this type of language
+ is also a design tool, it increases the language's
+ expressiveness.
+</p>
+<p>
+ C, pascal and C++ have type systems which are checked at
+ compile time, but can be defeated by straightforward means
+ provided by the language.
+</p>
+</section>
+
+<section><title>
+Why do we have to have yet another programming language; C++ (or Java,
+or Visual Basic) does everything.
+</title>
+<p>
+
+ It's undisputed that pretty much any programming language can
+ do what every other language can, so in that sense Erlang is
+ redundant.
+ </p><p>
+
+ On the other hand, we'd hope that some tools are better for
+ some things than other tools. Erlang was born from systematic
+ experiments to determine what would make a language good
+ at solving telecommunications-related problems, and
+ empirical evidence from large projects within Ericsson
+ suggests that Erlang succeeded in doing that.
+ </p><p>
+
+</p></section>
+<section><title>Erlang should use a Just In Time compiler</title>
+<p>
+
+ This might result in a faster Erlang system, or it might not.
+ It would be interesting to see some research done in this
+ area.
+
+</p></section>
+<section><title> Erlang should be object oriented</title>
+<p>
+ People coming to Erlang from object-oriented languages
+ sometimes spend a while trying to write programs in an
+ object-oriented style in Erlang before "seeing the light" and
+ realising that the benefits that may give in other languages
+ don't materialise in Erlang. Several papers have been
+ published about how to "do OO in Erlang", including a chapter
+ in the old (Armstrong, Virding, Wikström, Williams) Erlang
+ book.
+ </p><p>
+
+ A common conservative position is to say that processes,
+ asynchronous messages, functions and modules provide the
+ same ability to structure systems as do threads, classes,
+ methods, inheritance and aggregation.
+ </p><p>
+
+ An aggressive position is to say that OO is just
+ snake oil, that inheritance is error prone and
+ that any system which doesn't model concurrent problems
+ with concurrency in the program is defective. Taking
+ this position in newsgroups/mailing lists tends to trigger
+ a flamewar.
+ </p>
+</section>
+<section>
+ <marker id="string-performance"/>
+ <title>How are strings implemented and how can I speed up my string code?</title>
+<p>
+ Strings are represented as linked lists, so each character
+ takes 8 octets of memory on a 32 bit machine, twice as much on a 64
+ bit machine. Access to the Nth element is O(N). This makes it
+ easy to accidentally write O(N^2) code. Here's an example of
+ how that can happen:
+</p>
+
+ <code><![CDATA[
+ slurp(Socket) -> slurp(Socket, "").
+
+ slurp(Socket, Acc) ->
+ case gen_tcp:recv(Socket, 1) of
+ {ok, [Byte]} -> slurp(Socket, Acc ++ Byte);
+ _ -> Acc
+ end.
+ ]]></code>
+
+<p>
+ The bit-syntax provides an alternative way of handling
+ strings with different space/time tradeoffs to the
+ list implementation.
+</p>
+
+ <p>Some techniques for improving performance of string-related
+ code:
+</p>
+
+ <list>
+ <item><p>Avoid O(N^2) operations. Sometimes this means building
+ a longer string backwards and then using <c>reverse
+ </c>
+ in the final step. Other times, it's better to build
+ up a string as a list of lists and then let the io
+ functions flatten the list.
+ </p></item>
+
+ <item><p>Consider using an alternative representation of
+ your data, e.g. instead of representing the text as a
+ list of characters, it may be better to represent it as
+ a tree of words.
+ </p></item>
+
+ <item><p>If you're reading and writing data from sockets,
+ consider using binaries instead of lists of bytes. If
+ all you're doing is copying data from one socket to
+ another, this will be (much) faster. More generally,
+ the bit-syntax provides an alternative way of handling
+ strings with different space/time tradeoffs to the list
+ implementation.
+
+ </p></item>
+
+ <item><p>Write speed-critical (profile first!) code in C,
+ and then put it in your erlang system as a port-driver or a
+ linked-in driver.
+ </p></item>
+
+ <item><p>Ports (and sockets) flatten lists for you,
+ so flattening lists yourself slows things down.
+ This can also be used to create more readable code:
+ </p>
+<code><![CDATA[
+gen_tcp:send(Socket, ["GET ", Url, " HTTP/1.0", "\r\\n\r\\n"]).
+]]></code>
+
+ </item>
+ </list>
+
+</section>
+<section><title> How does the Garbage Collector work?</title>
+<p>
+ The current default GC is a "stop the world" generational
+ mark-sweep collector. Each Erlang process has its
+ own heap and these are collected individually, so
+ although every process is stopped while GC happens
+ for one processes, this stop time is expected to
+ be short because each process is expected to have a
+ small heap.
+ </p><p>
+
+ The GC for a new process is full-sweep. Once the process'
+ live data grows above a certain size, the GC switches to
+ a generational strategy. If the generational strategy
+ reclaims less than a certain amount, the GC reverts
+ to a full sweep. If the full sweep also fails to recover
+ enough space, then the heap size is increased.
+ </p><p>
+
+ In practice, this works quite well. It scales well
+ because larger systems tend to have more processes
+ rather than (just) larger processes. Measurements
+ in AXD301 (the large ATM switch) showed that about
+ 5% of CPU time is spent garbage collecting.
+ </p><p>
+
+ Problems arise when the assumptions are violated,
+ e.g. having processes with rapidly growing large heaps.
+
+ </p><p>
+ There are some alternative approaches to memory management
+ which can be enabled at run-time, including a <em>shared
+ heap</em>.
+
+
+</p></section>
+<section><title>Can I exploit knowledge about my program to make the GC more efficient?</title>
+<p>
+ Maybe, but you might be better off expending effort on
+ thinking of other ways to make your system go faster.
+ </p><p>
+
+ One version of <c>spawn/4</c> accepts a list of
+ options as the last argument. Ulf Wiger (AXD301) says
+ that the <c>gc_switch</c> and <c>min_heap_size</c> can be
+ used to obtain better performance if you do some measuring,
+ benchmarking and thinking. One 'win' happens when you can
+ completely avoid GC in short-lived processes by setting their
+ initial heap large enough to avoid all GC during the
+ process' life.
+ </p><p>
+
+ <c>min_heap_size</c> can be useful when you <em>know</em> that a
+ certain process will rapidly grow its heap to well above
+ the system's default size. Under such circumstances you get
+ particularly bad GC performance with the current GC
+ implementation.
+ </p><p>
+
+ <c>gc_switch</c> affects the point at
+ which the garbage collector
+ changes from its full-sweep algorithm to its generational
+ algorithm. Again, in a rapidly growing heap which doesn't
+ contain many binaries, GC <em>might</em> perform
+ better with a higher threshold.
+ </p><p>
+
+</p></section>
+<section><title>Could the Java Virtual Machine be used to run Erlang?</title>
+<p>
+ Yes, and it would be rather nice to be able
+ to benefit from the considerable effort being
+ put into making the JVM go faster.
+ </p><p>
+
+ There are a couple of obstacles: the JVM does
+ not provide support for tail recursion or
+ tagged data types. Both
+ of these deficiencies can be worked around at a cost.
+ The result will <em>probably</em> be slower and use
+ more memory than a VM written for Erlang.
+ </p><p>
+
+ Other languages with roughly similar characteristics to
+ Erlang have been written to run on the JVM. Benchmarks from
+ such systems (e.g. KAWA) show a significant performance
+ penalty from running on the JVM.
+ </p><p>
+
+</p></section>
+<section><title>Is it possible to prove the correctness of Erlang programs?
+</title>
+<p>
+
+ One of the touted advantages of functional programming
+ languages is that it is easier to formally reason about
+ programs and prove certain properties of a given program.
+ </p><p>
+
+ There is an active research group looking at problems
+ related to formal verification, they have a
+ <url href="http://www.sics.se/research/fdt.php">home page</url>.
+
+</p></section>
+<section><title>I've heard it's a bad idea to program defensively in Erlang. Why?</title>
+
+<p>
+ The <url href="http://www.erlang.se/doc/programming_rules.shtml">
+ Erlang coding guidelines</url> suggest avoiding defensive
+ programming. The choice of the term "defensive programming"
+ is unfortunate, because it is usually associated with good
+ practice. The point of the recommendation is that allowing
+ an Erlang process to exit when things go wrong inside the
+ Erlang program is a <em>good</em> approach, i.e.
+ writing code which attempts to avoid an exit is usually a bad idea.
+</p><p>
+ For example, when parsing an integer it makes perfect
+ sense to just write
+</p>
+
+ <code><![CDATA[
+ I = list_to_integer(L)
+ ]]></code>
+<p>
+ if L is not an integer, the process will exit and a supervisor
+ somewhere will restart that part of the system, reporting an
+ error:
+</p>
+
+ <code><![CDATA[
+ =ERROR REPORT==== 12-Mar-2003::13:04:08 ===
+ Error in process <0.25.0> with exit value: {badarg,[{erlang,list_to_integer,[bla]},{erl_eval,expr,3},{erl_eval,exprs,4},{shell,eval_loop,2}]}
+** exited: {badarg,[{erlang,list_to_integer,[bla]},
+ {erl_eval,expr,3},
+ {erl_eval,exprs,4},
+ {shell,eval_loop,2}]} **
+
+ ]]></code>
+
+<p>
+ If a more descriptive diagnostic is required, use a manual exit:
+</p>
+
+ <code><![CDATA[
+ uppercase_ascii(C) when C >= $a, C =< $z ->
+ C - ($a - $A);
+ uppercase_ascii(X) ->
+ exit({"uppercase_ascii given non-lowercase argument", X}).
+ ]]></code>
+<p>
+ This separation of error detection and error handling is a key
+ part of Erlang. It reduces complexity in fault-tolerant systems
+ by keeping the normal and error-handling code separate.
+</p><p>
+ As for most most advice, there are exceptions to the recommendation. One
+ example is the case where input is coming from an untrusted
+ interface, e.g. a user or an external program.
+</p><p>
+ Joe's
+ <url href="http://www.erlang.org/ml-archive/erlang-questions/200303/msg00113.html">original explanation</url> is available online.
+
+</p>
+</section>
+</chapter>
13 erlang_magic_file
@@ -0,0 +1,13 @@
+# OTP R3-R4
+0 string \0177BEAM! Old Erlang BEAM file
+>6 short >0 - version %d
+
+# OTP R5 and onwards
+0 string FOR1
+>8 string BEAM Erlang BEAM file
+
+# 4.2 version may have a copyright notice!!
+4 string Tue Jan 22 14:32:44 MET 1991 Erlang JAM file - version 4.2
+79 string Tue Jan 22 14:32:44 MET 1991 Erlang JAM file - version 4.2
+
+4 string 1.0 Fri Feb 3 09:55:56 MET 1995 Erlang JAM file - version 4.3
28 faq.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="iso-8859-1" ?>
+<!DOCTYPE part SYSTEM "part.dtd">
+<part>
+ <header>
+ <title>Frequently Asked Questions about Erlang</title>
+ <prepared></prepared>
+ <docno/>
+ <date>29. November 2007</date>
+ <rev/>
+ </header>
+
+ <description>
+ <p>A list of frequently asked questions (FAQ) and answers for
+the Erlang programming language.</p>
+ </description>
+
+ <include file="introduction"></include>
+ <include file="faq_questions"></include>
+ <include file="obtaining"></include>
+ <include file="getting_started"></include>
+ <include file="how_do_i"></include>
+ <include file="libraries"></include>
+ <include file="tools"></include>
+ <include file="implementations"></include>
+ <include file="problems"></include>
+ <include file="academic"></include>
+ <include file="mnesia"></include>
+</part>
133 faq_questions.xml
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="iso-8859-1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+<chapter>
+ <header>
+ <title>Questions about this FAQ</title>
+ <prepared>Matthias Lang</prepared>
+<docno></docno>
+<date>2007-09-12</date>
+ <rev>1.0</rev>
+ </header>
+
+<section><title>Where can I get the latest version of the FAQ?</title>
+<p>
+ The <url href="http://www.erlang.org/faq/faq.html">
+ open source Erlang website </url>.
+</p>
+</section>
+
+<section><title>What's new?</title>
+
+ <title>May 2009</title>
+ <p>Updated for R13B-1, fixed broken links</p>
+
+ <p>Updated the sections related to type checking to focus on
+ or mention dialyzer.</p>
+
+ <p>Added to the list of known high-profile commercial and
+ academic users.</p>
+
+ <p>Updated the conference section to cover the Erlang exchange
+ conferences in SF and London.</p>
+
+ <p>Mentioned the #erlang IRC channel.</p>
+ </section>
+
+ <section>
+
+
+ <section>
+
+ <title>January 2009</title>
+ <p>Updated for R12B-5, fixed broken links</p>
+
+ <p>Erlang now has public GIT, Bazaar and
+ CVS <seealso marker="obtaining#repositories">repositories</seealso></p>
+ </section>
+
+ <section>
+
+ <title>March 2008</title>
+ <p>Updated for R12B-1, fixed broken links</p>
+ </section>
+
+ <section>
+
+ <title>November 2007</title>
+ <p>Migrated the FAQ source from docbook to OTP's own docbuilder</p>
+ <p>Updated for R11B-5, fixed broken links</p>
+ <p>New question: <seealso marker="how_do_i#stderr">How do I
+ write to standard error on a unix system?</seealso></p>
+ </section>
+
+ <section>
+ <title>May 2007</title>
+ <p>Updated for R11B-4</p>
+
+ <p>Added a link to the new Joe Armstrong book.</p>
+
+ <p>New question: <seealso marker="obtaining#eeps">How can
+ I propose changes to the language itself?</seealso>
+ </p>
+
+
+ <p>New question: <seealso marker="academic#priority-receive">Can
+ a process receive messages with varying priorities?</seealso>
+ </p>
+
+ <p>Added CEAN (cean.process-one.net) to the 'obtaining' section.
+ </p>
+
+ <p>Removed the "why is the release so big?" question.
+ Given the bandwidth available to most people nowadays, the
+ question is no longer of general interest.
+ </p>
+ </section>
+
+</section>
+
+<section><title>Where do I ask questions which are not answered in this FAQ?</title>
+<p>
+ In most cases, the best place is the <em>erlang-questions</em>
+ mailing list at <url href="mailto:erlang-questions@erlang.org">
+ erlang-questions@erlang.org</url>. Anyone can
+ <url href="http://www.erlang.org/mailman/listinfo">subscribe.</url>
+</p>
+</section>
+
+<section><title>The answer to question 2.4 is wrong!</title>
+<p>
+ If you've found an editorial error in the FAQ (broken link,
+ an addition to a list of links, typo, ambiguity, badly
+ expressed answer, etc.), send some mail to
+ <url href="mailto:matthias@corelatus.com">
+ matthias@corelatus.com</url> and I'll fix it.
+</p>
+ <p>
+
+ Problems along the lines of "the advice about
+ the importance of type checking is complete drivel" might
+ be of general interest on the <em>erlang-questions</em>
+ mailing list at <url
+ href="mailto:erlang-questions@erlang.org?subject=besserwisser">
+ erlang-questions@erlang.org</url>.
+</p>
+</section>
+
+<section><title>Disclaimer/Distribution</title>
+<p>
+ The information in this document is available free of charge in the
+ hope that it will be of use. However, the author specifically
+ disclaims any liability for any direct, indirect, or consequential
+ damages arising out of its use. The author grants permission to
+ distribute this FAQ in unmodified form on any medium.
+</p>
+ <p>
+
+ Opinions in this FAQ do not necessarily agree with Ericsson's
+ official opinions. The
+ <url href="http://www.corelatus.com/~matthias">maintainer</url>
+ no longer works for Ericsson and this FAQ is not an Ericsson product.
+</p>
+</section>
+</chapter>
143 getting_started.xml
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="iso-8859-1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+<chapter>
+ <header>
+ <title>Getting Started</title>
+ <prepared>Matthias Lang</prepared>
+<docno></docno>
+<date>2007-09-12</date>
+ <rev>1.0</rev>
+ </header>
+
+<section><title>How long does it take to learn Erlang?</title>
+<p>
+
+ It depends. (did you expect anything else?)
+ </p><p>
+ With a C background (or Java, C++, Pascal, etc.),
+ it takes most people about a week before they can write
+ nontrivial programs, about a month to feel really comfortable
+ and a few months before feeling ready to take on something
+ big by themselves. It helps a lot to have someone who knows
+ how to use Erlang around for some hand-holding.
+ </p><p>
+ With a background which includes another declarative language
+ (Lisp, Prolog, Haskell, Scheme), you'll be able
+ to hack Erlang code straight away, though learning to take
+ advantage of the fault tolerance and concurrency takes a while.
+</p>
+</section>
+
+<section><title>How can I learn Erlang?</title>
+<p>
+
+ There's an <url href="http://www.erlang.org/course/course.html">
+ online tutorial</url>. Any of the
+ <seealso marker="obtaining#books"> Erlang books</seealso> can
+ also be used as tutorials.
+ </p><p>
+
+ The Erlang distribution includes a step-by-step <em>getting
+ started</em> guide. This is also <url
+href="http://www.erlang.org/doc/getting_started/part_frame.html"
+ >online</url>
+ </p><p>
+
+ <url href="http://www.erlang.se/training/index.shtml">
+ Ericsson</url> run training courses for Ericsson employees.
+ </p><p>
+
+ <url href="http://www.erlang-consulting.com/">erlang-consulting.com
+ </url> and <url
+ href="http://www.erlang-services.com/">erlang-services.com</url>
+ both run training courses (primarily in London and Stockholm,
+ but also in the US, Asia and Australia) aimed at
+ businesses.
+ </p><p>
+
+ Many <seealso marker="introduction#universities">universities
+ </seealso> run
+ courses either partly or wholly about Erlang. Courses about
+ functional programming are also useful for getting a solid
+ grounding which will then let you easily learn Erlang by yourself.
+</p>
+</section>
+
+<section><title>What does "hello world" look like?</title>
+<p>
+ Here's one way to write hello world:
+</p>
+
+ <code><![CDATA[
+ -module(hello).
+ -export([hello_world/0]).
+
+ hello_world() -> io:fwrite("hello, world\\n").
+ ]]></code>
+
+<p>
+ To compile this, save it in a file called <c>hello.erl</c> and
+ compile it from the erlang shell. Don't forget the full-stop
+ ("period" in American English) at the end of each command, as shown:
+</p>
+
+ <pre>
+ Erlang (BEAM) emulator version 4.9.1 [source]
+
+ Eshell V4.9.1 (abort with ^G)
+ 1> c(hello).
+ {ok,hello}
+ </pre>
+<p>
+
+ (on unix systems you start the erlang shell by typing "erl" at the
+ command line. On Windows, open a command prompt window and
+ type "werl", or find the Erlang icon in the programs menu).
+ To run the program from the Erlang shell:
+</p>
+
+ <pre>
+ 2> hello:hello_world().
+ hello, world
+ ok
+ </pre>
+</section>
+
+<section><title>How do I quit the Erlang shell?</title>
+<p>
+ To shut a system down cleanly, use <c>init:stop().</c>
+ </p><p>
+
+ Some quick ways are evaluating <c>halt().</c> or
+ <c>Control+\</c>.
+ </p><p>
+
+ <c>Control+C</c> and <c>Control+G</c>
+ give you access to menus.
+ </p>
+</section>
+
+<section><title>Why does Erlang print "ok" after my program's output?</title>
+<p>
+ The Erlang shell works by <em>r</em>eading an
+ Erlang expression,
+ <em>e</em>valuating it,
+ <em>p</em>rinting the result and
+ <em>l</em>ooping
+ for another expression, i.e. a REPL shell.
+ </p><p>
+
+ The <c>io:fwrite()</c> function does two things.
+ It prints out "hello world" and it returns the value
+ <c>ok</c>.
+ </p><p>
+
+ So, when you execute <c>io:fwrite("hello, world\n")
+ </c> in the shell, the <c>fwrite</c>
+ function prints the first line and the shell prints the return
+ value, <c>ok</c>. This can be
+ avoided by <seealso marker="how_do_i#noshell"> running
+ Erlang without a shell</seealso>.
+</p>
+</section>
+</chapter>
646 how_do_i.xml
@@ -0,0 +1,646 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+<chapter>
+ <header>
+ <title>How do I...</title>
+ <prepared>Matthias Lang</prepared>
+ <docno></docno>
+ <date>2007-09-12</date>
+ <rev>1.0</rev>
+ </header>
+
+
+ <p>
+ This section is intended for the impatient. Most of these
+ questions would resolved by working through the (on-line)
+ Erlang manuals, but sometimes we just want a quick answer...
+ </p><p>
+
+ Keep in mind that the program fragments are intended to
+ illustrate an idea, not serve as re-useable, robust modules!
+
+</p>
+
+ <section><title>...compare numbers?</title>
+ <p>
+
+ The operators for comparing numbers are <c> &gt;, &gt;=, &lt;,
+ =&lt;, == and =/= </c>. Some of these are a little different
+ to C for historical reasons. Here are some examples:
+ </p>
+
+ <pre>
+ Eshell V4.9.1 (abort with ^G)
+ 1> 13 > 2.
+ true
+ 2> 18.2 >= 19.
+ false
+ 3> 3 == 3.
+ true
+ 4> 4 =/= 4.
+ false
+ 5> 3 = 4.
+ ** exited: {{badmatch,4},[{erl_eval,expr,3}]} **
+ </pre>
+
+ <p>
+ The last example is a (failed) pattern match rather than a
+ comparison.
+ </p>
+
+ </section>
+ <section><title>...represent a text-string?</title>
+
+ <p>
+ As a list of characters. You can write
+ </p>
+
+ <pre>A = "hello world".</pre>
+
+ <p> which is exactly the same as writing</p>
+
+ <pre>A = [104,101,108,108,111,32,119,111,114,108,100].
+ </pre>
+
+ <p>and also the same as writing</p>
+
+ <pre>A = [$h,$e,$l,$l,$o,$ ,$w,$o,$r,$l,$d].</pre>
+
+ <p>
+ Each character consumes 8 bytes of memory on a 32 bit
+ machine (a 32 bit integer and a 32 bit pointer) and twice
+ as much on 64 bit machines. Access to the nth. element takes
+ O(n) time. Access to the first element takes O(1) time, as
+ does prepending a character.
+ </p><p>
+
+ The bit-syntax, which is described in <url
+ href="http://www.erlang.org/doc/reference_manual/expressions.html#6.16">
+ the manual</url> provides an alternative, but somewhat
+ limited, way to represent strings compactly, for instance:
+</p>
+
+ <pre><![CDATA[
+ 1> A = <<"this string consumes one byte per character">>.
+ <<116,104,105,115,32,115,116,114,...>>
+ 2> size(A).
+ 43
+ 3> <<_:8/binary,Q:3/binary,R/binary>> = A.
+ <<116,104,105,115,32,115,116,114,...>>
+ 4> Q.
+ <<105,110,103>>
+ 5> binary_to_list(Q).
+ "ing"
+ ]]></pre>
+ <p>
+ This style of pattern-matching manipulation of strings
+ provides O(1) equivalents of some string operations which are
+ O(N) when using the list representation. Some other operations
+ which are O(1) in the list representation become O(N) when
+ using the bit-syntax.
+ </p><p>
+
+ There are general ways to
+ <seealso marker="academic#string-performance">improve
+ string performance.</seealso>
+
+</p></section>
+ <section><title>...convert a string to lower case?</title>
+
+ <pre>
+ 1> string:to_lower("Five Boxing WIZARDS").
+ "five boxing wizards"
+ 2> string:to_upper("jump QuickLY").
+ "JUMP QUICKLY"
+ </pre>
+
+ <p>
+ If you have an older version of Erlang (prior to R11B-5), you can
+ find these two functions in the <c>httpd_util</c> module.
+ </p>
+ </section>
+
+ <section>
+ <marker id="howto-string-to-term"/>
+ <title>...convert a text string representation of a term to a term?</title>
+
+ <pre>
+ 1> {ok,Tokens,_} = erl_scan:string("[{foo,bar},x,3].").
+ {ok,[{'[',1}, {'{',1}, {atom,1,foo}, {',',1}, {atom,1,bar},...
+ 2> {ok,Term} = erl_parse:parse_term(Tokens).
+ {ok,[{foo,bar},x,3]}
+ </pre>
+
+ <p>
+ See also <c>file:consult/1</c>
+ </p></section>
+
+ <section><title>...use unicode/UTF-8?</title>
+ <p>
+
+ Representing strings as lists of integers also has advantages,
+ one of which is that unicode (and any other character encodings)
+ is automatically supported in the sense that you can pass around
+ lists of unicode characters.
+ </p><p>
+
+ In practice, supporting unicode means a bit more, for instance
+ being able to read unicode from a file and being able to sort
+ unicode strings.
+ </p><p>
+
+ There is some undocumented code in the OTP XMERL application
+ (the xmerl_ucs module) to help with some of that.
+ </p><p>
+
+ There's also <url href="http://12monkeys.co.uk/starling/">alpha
+ code</url> to help with basic operations over
+ unicode strings: comparison, concatention, substring extraction,
+ substring search and case conversion.
+
+</p></section>
+ <section><title>...destructively update data, like in C</title>
+ <p>
+ Not being able to do this is considered a feature of Erlang. The
+ <url href="http://www.erlang.org/download/erlang-book-part1.pdf">
+ Erlang book</url> explains this in chapter 1.
+
+<!-- REVISIT: I should read Joe's book and find a relevant passage there instead -->
+</p><p>
+ Having said that, there are common methods to achieve
+ effects similar to destructive update: store the data
+ in a process (use messages to manipulate it), store the data
+ in ETS or use a data structure designed
+ for relatively cheap updates (the <c>dict</c> library
+ module is one common solution).
+
+</p></section>
+ <section>
+ <marker id="noshell"/>
+ <title>...run an Erlang program directly from the unix shell?</title>
+ <p>
+ As of Erlang/OTP R11B-4, you can run Erlang code without
+ compiling by using Escript. The <url href="http://www.erlang.org/doc/man/escript.html">manual page</url> has a
+ complete example showing how to do it.
+
+ </p><p>
+ Escript is intended for short, "script-like" programs. A more
+ general way to do it, which also works for older Erlang releases,
+ is to start the Erlang VM without a shell and pass more switches
+ to the Erlang virtual machine. Here's hello world again:
+ </p>
+
+ <code>
+ -module(hello).
+ -export([hello_world/0]).
+
+ hello_world() ->
+ io:fwrite("hello, world\\n").
+ </code>
+
+ <p>
+ Save this as <c>hello.erl</c>, compile it and
+ run it directly from the unix (or msdos) command line:
+ </p>
+
+ <pre>
+ matthias >erl -compile hello
+ matthias >erl -noshell -s hello hello_world -s init stop
+ hello, world
+ </pre>
+
+ </section>
+ <section><title>...communicate with non-Erlang programs?</title>
+ <p>
+
+ Erlang has several mechanisms for communicating with programs
+ written in other languages, each with different tradeoffs. The
+ Erlang documentation includes a
+ <url href=
+ "http://www.erlang.org/doc/tutorial/part_frame.html">
+ guide to interfacing with other languages</url> which describes
+ the most common mechanisms:
+</p>
+
+ <list>
+ <item><p>Distributed Erlang</p></item>
+ <item><p>Ports and linked-in drivers</p></item>
+ <item><p>EI (C interface to Erlang, replaces the
+ mostly deprecated erl_interface)</p></item>
+ <item><p>Jinterface (Java interface to Erlang)</p></item>
+ <item><p>IC (IDL compiler, used with C or Java)</p></item>
+ <item><p>General TCP or UDP protocols, including ASN.1</p></item>
+ </list>
+
+ <p>
+ Some of the above methods are easier to use than others. Loosely
+ coupled approaches, such as using a custom protocol over a TCP socket,
+ are easier to debug than the more tightly coupled options such as
+ linked-in drivers. The Erlang-questions mailing list archives
+ contain many desperate cries for help with memory corruption problems
+ caused by using Erl Interface and linked-in drivers incorrectly...
+ </p><p>
+ There are a number of user-supported methods and tools, including
+</p>
+ <list>
+ <item><p><url href="http://epi.sourceforge.net/">A set of C++ classes</url></p></item>
+ <item><p><url href="http://www.lysator.liu.se/~tab/erlang/py_interface/">A Python implementation of an Erlang hidden node</url></p></item>
+ <item><p><url href="http://www.snookles.com/erlang/edtk/">
+ EDTK, a port-driver toolkit,</url> roughly equivalent
+ to Java's SWIG.</p></item>
+ <item><p><url href="http://dryverl.objectweb.org/">Dryverl,
+ an Erlang-to-C binding</url>.</p></item>
+ </list>
+
+ </section>
+ <section><title>...write a unix pipe program in Erlang?</title>
+ <p>
+
+ Lots of useful utilities in unix can be chained together
+ by piping one program's output to another program's input.
+ Here's an example which rot-13 encodes standard input
+ and sends it to standard output:
+
+ </p>
+ <code><![CDATA[
+ -module(rot13).
+ -export([rot13/0]).
+
+ rot13() ->
+ case io:get_chars('', 8192) of
+ eof -> init:stop();
+ Text ->
+ Rotated = [rot13(C) || C &lt;- Text],
+ io:put_chars(Rotated),
+ rot13()
+ end.
+
+ rot13(C) when C >= $a, C =&lt; $z -> $a + (C - $a + 13) rem 26;
+ rot13(C) when C >= $A, C =&lt; $Z -> $A + (C - $A + 13) rem 26;
+ rot13(C) -> C.
+ ]]></code>
+
+ <p>
+ After compiling this, you can run it from the command line:
+
+ </p>
+ <pre>
+ matthias> cat ~/.bashrc | erl -noshell -s rot13 rot13 | wc
+ </pre>
+
+ </section>
+ <section><title>...communicate with a DBMS?</title>
+ <p>
+
+ There are two completely different ways to communicate with
+ a database. One way is for Erlang to act as a database for
+ another system. The other way is for an Erlang program to
+ access a database. The former is a "research" topic. The
+ latter is easily accomplished by going via ODBC, which allows
+ you to access almost any commercial DBMS. The
+ <url href=
+ "http://www.erlang.org/doc/apps/odbc/index.html">
+ OTP ODBC manual</url> explains how to do this.
+
+</p></section>
+ <section><title>...decode binary Erlang terms</title>
+ <p>
+
+ Erlang terms can be converted to and from binary representations
+ using bifs:
+
+ </p>
+ <code><![CDATA[
+ 1> term_to_binary({3, abc, "def"}).
+ <<131,104,3,97,3,100,0,3,97,98,99,107,0,3,100,101,102>>
+ 2> binary_to_term(v(1)).
+ {3,abc,"def"}
+ ]]></code>
+
+ <p>
+
+ If you want to decode them using C programs, take a look
+ at <url href="http://erlang.org/doc/man/ei.html">EI</url>.
+
+</p></section>
+ <section><title>...decode Erlang crash dumps</title>
+ <p>
+
+ Erlang crash dumps provide information about the state of the
+ system when the emulator crashed. The
+ <url href="http://erlang.org/doc/apps/erts/crash_dump.html">manual explains</url> how to interpret them.
+
+
+</p></section>
+ <section><title>...estimate performance of an Erlang system?</title>
+ <p>
+
+ Mike Williams, one of Erlang's original developers, is fond
+ of saying
+</p> <quote><p>"If you don't run experiments before
+ you start designing a <em>new</em> system, your
+ <em>entire system</em> will be an experiment!"</p></quote>
+ <p>
+
+ This philosophy is widespread around Erlang projects, in part
+ because the Erlang development environment encourages development
+ by prototyping. Such prototyping will also allow sensible
+ performance estimates to be made.
+ </p><p>
+
+ For those of you who want to leverage experience with C
+ and C++, some rough rules of thumb are:
+ </p>
+
+ <list>
+ <item><p>Code which involves mainly number crunching and
+ data processing will run about 10 times slower than
+ an equivalent C program. This includes almost all
+ "micro benchmarks"</p></item>
+
+ <item><p>Large systems which spent most of their time
+ communicating with other systems, recovering from faults and
+ making complex decisions run at least as fast as equivalent
+ C programs.</p></item>
+ </list>
+
+ <p>
+ Like in any other language or system, experienced developers
+ develop a sense of which operations are expensive and which
+ are cheap. Erlang newcomers accustomed to the relatively slow
+ interprocess communication facilities in other languages
+ tend to over-estimate the cost of creating Erlang processes and
+ passing messages between them.
+
+</p></section>
+ <section><title>...measure performance of an Erlang system?</title>
+ <p>
+
+ The <em>timer</em> module measures the wall clock time
+ elapsed during execution of a function:
+
+ </p>
+ <code>
+ 7> timer:tc(lists, reverse, ["hello world"]).
+ {27,"dlrow olleh"}
+ 8> timer:tc(lists, reverse, ["hello world this is a longer string"]).
+ {34,"gnirts regnol a si siht dlrow olleh"}
+ </code>
+
+ <p>
+
+ The <c>eperf</c> library provides a way to profile
+ a system.
+
+</p></section>
+ <section><title>...measure memory consumption in an Erlang system?</title>
+ <p>
+
+ Memory consumption is a bit of a tricky issue in Erlang. Usually,
+ you don't need to worry about it because the garbage collector
+ looks after memory management for you. But, when things go
+ wrong, there are several sources of information. Starting
+ from the most general:
+</p><p>
+ Some operating systems provide detailed information
+ about process memory use with tools like top,
+ ps or the linux /proc filesystem:
+</p>
+
+ <pre>
+ cat /proc/5898/status
+
+ VmSize: 7660 kB
+ VmLck: 0 kB
+ VmRSS: 5408 kB
+ VmData: 4204 kB
+ VmStk: 20 kB
+ VmExe: 576 kB
+ VmLib: 2032 kB
+ </pre>
+
+ <p>
+ This gives you a rock-solid upper-bound on the amount of
+ memory the entire Erlang system is using.
+</p><p>
+ <c>erlang:system_info</c> reports
+ interesting things about some globally allocated structures in bytes:
+</p>
+
+ <pre>
+ 3> erlang:system_info(allocated_areas).
+ [{static,390265},
+ {atom_space,65544,49097},
+ {binary,13866},
+ {atom_table,30885},
+ {module_table,944},
+ {export_table,16064},
+ {register_table,240},
+ {loaded_code,1456353},
+ {process_desc,16560,15732},
+ {table_desc,1120,1008},
+ {link_desc,6480,5688},
+ {atom_desc,107520,107064},
+ {export_desc,95200,95080},
+ {module_desc,4800,4520},
+ {preg_desc,640,608},
+ {mesg_desc,960,0},
+ {plist_desc,0,0},
+ {fixed_deletion_desc,0,0}]
+ </pre>
+
+ <p>
+ Information about individual processes can be obtained
+ from <c>erlang:process_info/1</c> or
+ <c>erlang:process_info/2</c>:
+</p>
+ <pre>
+ 2> erlang:process_info(self(), memory).
+ {memory,1244}
+ </pre>
+ <p>
+ The shell's <c>i()</c> and the <c>pman
+ </c> tool also give useful overview information.
+</p><p>
+ Don't expect the sum of the results from <c>process_info
+ </c> and <c>system_info</c> to add up to
+ the total memory use reported by the operating system. The Erlang
+ runtime also uses memory for other things.
+</p><p>
+ A typical approach when you suspect you have memory problems
+ is
+</p><p>
+ 1. Confirm that there really is a memory problem by checking
+ that memory use as reported by the operating system is unexpectedly
+ high.
+</p><p>
+ 2. Use <c>pman</c> or the shell's <c>
+ i()</c> command to make sure there isn't an out-of-control
+ erlang process on the system. Out-of-control processes often have
+ enormous message queues. A common reason for Erlang processes to
+ get unexpectedly large is an endlessly looping function which isn't
+ tail recursive.
+</p><p>
+ 3. Check the amount of memory used for binaries (reported
+ by <c>system_info</c>). Normal data in Erlang is
+ put on the process heap, which is garbage collected. Large binaries,
+ on the other hand, are reference counted. This has two interesting
+ consequences. Firstly, binaries don't count towards a process'
+ memory use. Secondly, a lot of memory can be allocated in binaries
+ without causing a process' heap to grow much. If the heap doesn't
+ grow, it's likely that there won't be a garbage collection, which
+ may cause binaries to hang around longer than expected. A
+ strategically-placed call to <c>erlang:garbage_collect()
+ </c> will help.
+</p><p>
+ 4. If all of the above have failed to find the problem,
+ start the Erlang runtime system with the -instr switch.
+
+</p></section>
+ <section><title>...estimate productivity in an Erlang project?</title>
+ <p>
+
+ A rough rule of thumb is that about the same number of lines
+ of code are produced per developer as in a C project.
+ A reasonably complex problem involving distribution and
+ fault tolerance will be roughly five times shorter in
+ <em>Erlang</em> than in C.
+ </p><p>
+
+ The traditional ways of slowing down projects, like adding
+ armies of consultants halfway through,
+ spending a year writing detailed design specifications
+ before any code is written, rigidly following a waterfall
+ model, spreading development across several countries and
+ holding team meetings to decide on the colour of the serviettes used
+ at lunch work just as well for Erlang as for other languages.
+
+</p></section>
+ <section><title>...use multiple CPUs (or cores) in one server?</title>
+ <p>
+ As of OTP R12B, Erlang has SMP support on all the major
+ platforms, and it's enabled by default. Some platforms
+ (Solaris, Linux, MacOSX on PPC) had SMP support in earlier
+ versions.
+</p><p>
+ Given that Erlang programs are naturally written in a concurrent
+ manner, most programs require no modification at all to take
+ advantage of SMP.
+</p><p>
+ A more loosely coupled approach is to start multiple Erlang nodes
+ on the same server.
+
+</p></section>
+ <section><title>...run distributed Erlang through a firewall?</title>
+ <p>
+ The simplest approach is to make an a-priori restriction to the
+ TCP ports distributed Erlang uses to communicate through by
+ setting the (undocumented) kernel variables 'inet_dist_listen_min'
+ and 'inet_dist_listen_max'. Example:
+</p>
+
+ <pre>
+ application:set_env(kernel, inet_dist_listen_min, 9100).
+ application:set_env(kernel, inet_dist_listen_max, 9105).
+ </pre>
+
+ <p>
+ This forces Erlang to use only ports 9100--9105 for distributed
+ Erlang traffic.
+
+ In the above example, you would then need to configure your
+ firewall to pass ports 9100--9105 as well as port 4369 (for
+ the erlang port mapper).
+</p><p>
+ There are other approaches, such as tunnelling the information
+ through SSH or writing your own distribution handler.
+
+</p></section>
+ <section>
+ <marker id="crash-line-number"/>
+ <title>...find out which line my Erlang program crashed at?</title>
+ <p>
+ The run-time system's error reports tell you which function
+ crashed, but not the line number. Consider this module:
+</p>
+
+ <pre>
+ -module(crash).
+ -export([f/0]).
+
+ f() ->
+ g().
+
+ g() ->
+ A = 4,
+ b = 5, % Error is on this line.
+ A.
+ </pre>
+
+ <pre>
+ 3> crash:f().
+ ** exited: {{badmatch,5},[{crash,g,0},{shell,exprs,6},{shell,eval_loop,3}]} **
+ </pre>
+
+ <p>
+ The crash message tells us that the crash was in the function
+ <c>crash:g/1</c>, and that it was a badmatch. For
+ programs with short functions, this is enough information for
+ an experienced programmer to find the problem.
+</p><p>
+ In cases where you want more information, there are two options.
+ The first is to use the <url href="http://www.erlang.org/doc/apps/debugger/">erlang debugger</url> to single-step
+ the program.
+</p><p>
+ Another option is to compile your code using the smart
+ exceptions package, available from
+ <url href='http://jungerl.cvs.sourceforge.net/jungerl/jungerl/lib/smart_exceptions/src/'>the jungerl</url>. Smart exceptions then provide line
+ number information:
+</p>
+
+ <pre>
+ 4> c(crash, [{parse_transform, smart_exceptions}]).
+ {ok,crash}
+ 5> crash:f().
+ ** exited: {{crash,g,0},{line,9},match,[5]} **
+ </pre>
+
+ </section>
+ <section>
+ <marker id="erlrt-and-sae"/>
+ <title>...distribute the Erlang programs I write to my friends/colleagues/users?</title>
+
+ <p>
+ Erlang programs only run on the Erlang VM, so every machine which
+ is going to run an Erlang program needs to have a copy of the
+ Erlang runtime installed.
+</p><p>
+ Installing the entire Erlang system from erlang.org (or, perhaps,
+ indirectly via a packaging system such as Debian's or BSD's) is
+ the simplest option in many cases.
+</p><p>
+ A more modular alternative is to install the
+ <url href="http://cean.process-one.net/">CEAN</url>
+ runtime.
+</p><p>
+ A further alternative which has fallen into disuse is SAE:
+ stand-alone Erlang. SAE allows an Erlang program to be distributed
+ as just two files, totalling about 500k. SAE no longer works
+ on current Erlang releases, but for historical interest, there is
+ <url href="http://www.sics.se/~joe/sae.html">
+ a page about SAE</url> which shows you how to build a self-contained
+ system for the (somewhat outdated) R9B Erlang release.
+
+</p></section>
+ <section>
+ <marker id="stderr"/>
+ <title>...write to standard error (stderr) on a unix system?</title>
+
+ <p>The simplest approach is to just open file descriptor two:</p>
+
+ <code>
+ P = open_port({fd,0,2}, [out]),
+ port_command(P, "this text goes to stderr\\n").
+ </code>
+ </section>
+</chapter>
265 implementations.xml
@@ -0,0 +1,265 @@
+<?xml version="1.0" encoding="iso-8859-1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+<chapter>
+ <header>
+ <title>Implementation and Ports of Erlang</title>
+ <prepared>Matthias Lang</prepared>
+<docno></docno>
+<date>2007-09-12</date>
+ <rev>1.0</rev>
+ </header>
+
+<section>
+ <marker id="implementations"/>
+ <title>What Production-quality implementations of Erlang are there?</title>
+
+ <list>
+ <item><p> <url href="http://www.erlang.org/"> Open Source
+ Erlang </url>
+ is the most popular implementation.
+ It is built from the same source tree as the commercial
+ version of Erlang. You can use Open Source Erlang to build
+ commercial products without having to pay royalties or licence
+ fees to Ericsson.
+ <marker id="commercial-erlang"/>
+ </p></item>
+
+
+ <item><p> <url href="http://www.erlang.se/">
+ Ericsson's Commercial Erlang</url>. This is essentially
+ the same as Open Source Erlang. The main differences are:
+ </p>
+
+ <list>
+ <item><p>Commercial Erlang comes with a support agreement
+ </p></item>
+
+ <item><p>The OTP team go to greater lengths
+ to test the commercial release, so you
+ get a more stable product. Similarly, they
+ make the transition between versions smoother.
+ </p></item>
+
+ <item><p>The commercial version includes some
+ encryption-related code which cannot be
+ provided in the open source release for legal reasons.
+ </p></item>
+
+ <item><p>The commercial release does <em>not
+ </em> contain applications which are
+ considered experimental or unstable.
+ </p></item>
+
+ </list>
+ </item>
+ </list>
+
+</section>
+<section><title>What Experimental and Research Implementations are there?</title>
+
+ <list>
+
+ <item><p><url
+ href="http://www.it.uu.se/research/group/hipe">
+ High Performance Erlang</url> (HIPE).
+ HIPE is an in-progress project to create a faster Erlang
+ by compiling to native code. Since R8A, the HIPE compiler
+ is tightly integrated with the normal BEAM system; if
+ you have downloaded open source erlang, then you also have
+ HIPE. A <url href="http://www.erlang.se/euc/01/kostis2001/sld001.htm">presentation at the EUC 2001</url> described how to use it.</p></item>
+
+ <item><p>
+ <url href="http://www.iro.umontreal.ca/~etos/">
+ Erlang to Scheme Compiler</url> (ETOS).
+ ETOS is another research project to compile Erlang
+ programs to native code by first translating the
+ program into scheme. They have some impressive benchmarks.
+ ETOS is no longer under active development.</p></item>
+
+ <item><p>
+ Geoff's Erlang (GERL) supported a subset of the Erlang
+ language. GERL compiled to native code via C. GERL has
+ fallen into disuse.</p></item>
+
+ <item><p><url
+ href="http://www.adfa.edu.au/~lpb/research/sserl/">
+ Safe Erlang</url>,
+ which is a prototype made by extending an older version
+ of Ericsson's implementation, is intended for
+ applications where Erlang nodes must cooperate with
+ other Erlang nodes which are not trusted. Safe Erlang
+ is no longer under active development.</p></item>
+
+ </list>
+
+</section>
+<section>
+ <marker id="version-table"/>
+ <title> Which version of Erlang am I running?</title>
+ <p>
+ Erlang uses different version numbers for different parts
+ of the system, so the message you see when you start Erlang
+ doesn't reveal which release you're using:
+</p>
+ <pre>
+ Erlang (BEAM) emulator version 5.1.1 [source]
+
+ Eshell V5.1.1 (abort with ^G)
+ </pre>
+
+<p>
+ The start script reveals more information:
+</p>
+
+ <pre>
+ Eshell V5.3.6.3 (abort with ^G)
+ 1> init:script_id().
+ {"OTP APN 181 01","R9C"}
+ </pre>
+
+</section>
+<section><title> What operating systems does Erlang run on?</title>
+<p>
+
+ Erlang runs on most unix and unix-like systems and on the
+ currently popular flavours of windows. Ericsson
+ have compiled it for
+</p>
+
+ <list>
+ <item><p> Solaris (including 64 bit)</p></item>
+ <item><p> BSD</p></item>
+ <item><p> Linux</p></item>
+ <item><p> OSX</p></item>
+ <item><p> TRU64</p></item>
+ <item><p> Windows NT/2000/2003/XP/Vista</p></item>
+ <item><p> VxWorks</p></item>
+ </list>
+
+ <p>
+
+ There are reports on the mailing list of other people
+ compiling it successfully IRIX, along with reports of
+ Erlang running on less usual systems such as iPhones, Xboxes
+ Tilera 64-core CPUs and many embedded systems.
+ </p><p>
+
+</p></section>
+<section><title> What implementations of the Erlang Virtual Machine are there?</title>
+<p>
+
+ Almost everyone uses "the new BEAM", where BEAM stands
+ for Bogdan/Bj&ouml;rn's Erlang Abstract Machine. This is
+ the virtual machine supported in the commercial release.
+ </p><p>
+
+ The other virtual machines are of mostly historical interest:
+</p>
+ <section>
+ <title>JAM</title><p>
+
+ This was the original Erlang virtual machine,
+ inspired by the (Prolog) WAM. JAM stands for
+ "Joe's Abstract Machine".</p>
+
+ </section>
+ <section>
+ <title>old BEAM</title><p>
+
+ This was an attempt to compile Erlang
+ to C, and then compile the C to native code. It was
+ abandoned after benchmarking showed that the resulting
+ code was only faster than VM-based Erlang for small programs.
+</p>
+ </section>
+
+</section>
+<section><title>Is there an unofficial port for...?</title>
+<p>
+
+ <em>MacOS X</em>: Releases since R9B compile on
+ MacOS X.
+ </p><p>
+
+ <em>QNX</em>: Vlad Dumitrescu has looked
+ at porting to QNX. If you're interested, ask on the
+ erlang mailing list.</p><p>
+
+ <em>VxWorks</em>: VxWorks support is
+ included in the standard distribution. </p><p>
+
+</p></section>
+<section>
+ <marker id="cygwin-cross"/>
+ <title>Can Erlang be compiled under Microsoft Windows?</title>
+<p>
+
+ There is a README.win32 file at the top of the source code
+ distribution which explains how to do this.
+
+</p></section>
+
+<section><title>Can Erlang be cross compiled?</title>
+<p>
+
+ Yes, with a moderate amount of effort. There's a fairly
+ <url href='http://www.trapexit.org/Cross_compiling'>
+ detailed writup</url> on the trapexit wiki which covers
+ cross compiling between linux systems.
+
+ </p><p>
+ Patrik Nyblom posted a <url
+href="http://www.erlang.org/ml-archive/erlang-questions/200003/msg00013.html">
+ step-by-step VxWorks cross-compiling guide</url>
+ to the mailing list.
+
+ </p><p>
+ Brian Zhou has <url href='http://www.erlang.org/ml-archive/erlang-questions/200507/msg00014.html'>posted instructions</url> and a relatively simple patch to
+ erts/configure.in which allows cross compilation for many (most?)
+ linux targets.
+
+</p></section>
+<section><title>Is Erlang small enough for Pocket PCs?</title>
+<p>
+
+ Various people on the erlang-questions mailing list have reported
+ Erlang running on pocket PCs, including the
+ <url href="http://dynamism.com/sl-c3000/main.shtml">Sharp Zaurus</url>.
+
+</p></section>
+<section><title>Is Erlang small enough for embedded systems?</title>
+<p>
+
+ Rule of thumb: if the embedded system can run an
+ operating system like linux, then it is probably possible
+ to get current implementations of Erlang running on it
+ with a reasonable amount of effort.
+
+ Getting Erlang to run on, say, an 8 bit CPU with 32kByte of
+ RAM is not feasible.
+
+ People successfully run the Ericsson implementation of
+ Erlang on systems with as little as 16MByte of RAM. It
+ is reasonably straightforward to fit Erlang itself into
+ 2MByte of persistant storage (e.g. flash or hard disk).
+ </p><p>
+
+ A 2MByte stripped Erlang system can include the
+ beam emulator and almost all of the stdlib, sasl,
+ kernel, inets and runtime_tools libraries, provided
+ the libraries are compiled without debugging information
+ and are compressed:
+ </p>
+
+ <code>
+ compile:file("foo", [compressed,no_debug_info]).
+ </code>
+
+ <p>
+ This can be automated by editing otp.mk.in and adding
+ <c>+compressed +no_debug_info</c>
+ to the erlang compiler options and then rebuilding all the libraries.
+</p>
+
+</section>
+</chapter>
318 introduction.xml
@@ -0,0 +1,318 @@
+<?xml version="1.0" encoding="iso-8859-1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+<chapter>
+ <header>
+ <title>What is Erlang</title>
+ <prepared>Matthias Lang</prepared>
+ <docno></docno>
+ <date>2007-09-12</date>
+ <rev>1.0</rev>
+ </header>
+
+<section><title>In a nutshell, what is Erlang?</title>
+<p>
+
+ Erlang is a general-purpose programming language and
+ runtime environment. Erlang has built-in support for
+ concurrency, distribution and fault tolerance. Erlang
+ is used in several large telecommunication systems
+ from <url href="http://www.ericsson.com/">Ericsson</url>.
+ Erlang is available as open
+ source from <url href="http://www.erlang.org/">
+ http://www.erlang.org</url>.
+</p>
+</section>
+
+<section><title>What is OTP?</title>
+<p>
+
+ OTP (Open Telecom Platform) is a large collection of libraries
+ for Erlang to do
+ everything from compiling ASN.1 to providing a WWW server.
+ Most projects using "Erlang" are actually using "Erlang/OTP",
+ i.e. the language and the libraries. OTP is also open source.
+</p>
+
+</section>
+<section><title>What sort of applications is Erlang particularly suitable for?
+</title>
+<p>
+ Distributed, reliable, <seealso marker="academic#soft-realtime">
+ soft real-time</seealso> concurrent systems.
+</p>
+
+ <list>
+ <item><p> Telecommunication systems, e.g. controlling a switch
+ or converting protocols.</p></item>
+
+ <item><p> Servers for Internet applications, e.g. a
+ mail transfer agent, an IMAP-4 server, an HTTP server or a
+ <url href="http://www.erlang.se/euc/99/WAP/index.htm">
+ WAP Stack</url>.</p></item>
+
+ <item><p> Telecommunication applications, e.g. handling
+ mobility in a mobile network or providing unified messaging.
+ </p></item>
+
+ <item><p> Database applications which require soft realtime
+ behaviour.</p></item>
+ </list>
+<p>
+ Erlang is good at solving these sorts of problems because
+ this is the problem domain it was originally designed for.
+ Stating the above in terms of features:
+</p>
+
+ <list>
+ <item><p> Erlang provides a simple and powerful model
+ for error containment and fault tolerance
+ (supervised processes).</p></item>
+
+ <item><p> Concurrency and message passing are a fundamental
+ to the language. Applications written in Erlang
+ are often composed of hundreds or thousands of
+ lightweight processes. Context switching between
+ Erlang processes is typically one or two orders
+ of magnitude cheaper than switching between
+ threads in a C program.</p></item>
+
+ <item><p> Writing applications which are made of parts which
+ execute on different machines (i.e. distributed
+ applications) is easy. Erlang's distribution
+ mechanisms are transparent: programs need not be
+ aware that they are distributed.</p></item>
+
+ <item><p> The OTP libraries provide support for many common
+ problems in networking and telecommunications systems.
+ </p></item>
+
+ <item><p> The Erlang runtime environment (a virtual machine,
+ much like the Java virtual machine) means that code
+ compiled on
+ one architecture runs anywhere. The runtime system
+ also allows code in a running system to be updated
+ without interrupting the program.
+ </p></item>
+ </list>
+
+<p>
+ The <url href="http://www.erlang.org/white_paper.html">
+ Erlang white paper</url> examines the language in more detail
+ from a technical point of view.
+</p>
+</section>
+<section><title>What sort of problems is Erlang not particularly suitable for?
+</title>
+<p>
+ People use Erlang for all sorts of surprising things, for instance
+ to communicate with X11 at the protocol level, but, there are some
+ common situations where Erlang is not likely to be the language of
+ choice.
+</p>
+ <p>
+
+ The most common class of 'less suitable' problems is
+ characterised by performance being
+ a prime requirement <em>and</em> constant-factors
+ having a large effect on performance. Typical examples are
+ image processing, signal processing, sorting large
+ volumes of data and low-level protocol termination.
+</p>
+ <p>
+
+ Another class of problem is characterised by a wide interface
+ to existing C code. A typical example is implementing operating
+ system device drivers.
+</p>
+ <p>
+
+ Most (all?) large systems developed using Erlang make heavy use
+ of C for low-level code, leaving Erlang
+ to manage the parts which tend to be complex in other languages,
+ like controlling systems spread across several machines and
+ implementing complex protocol logic.
+
+</p>
+</section>
+<section> <title> Who uses Erlang for product development?</title>
+<p>
+
+ The largest user of Erlang is Ericsson. Ericsson use it to
+ write software used in telecommunications systems. Many
+ (dozens) projects have used it, a particularly large one is
+ the extremely scaleable
+
+ <url href="http://www.ericsson.com/ericsson/corpinfo/publications/review/2000_03/files/2000031.pdf">
+ AXD301 ATM switch.</url>
+ AXD301 has several hundred people working on it and the code volume
+ has reached about 850 kloc of Erlang (and 1 Mloc of C/C++).
+</p>
+ <p>
+
+ Some of the other companies using Erlang are
+ </p>
+
+ <list>
+ <item><p>
+ <url href="http://www.nortel.com/">Bluetail/Alteon/Nortel</url>
+ (distributed, fault tolerant email system, SSL accelerator)
+ </p></item>
+ <item><p>
+ <url href="http://www.cellpoint.com/">Cellpoint</url>
+ (Location-based Mobile Services)
+ </p></item>
+
+ <item><p>
+ <url href="http://www.corelatus.com/">Corelatus</url>
+ (SS7 monitoring).
+ </p></item>
+
+ <item><p>
+ <url href="http://counter.hackers.lv/">dqdp.net (in Latvian)</url>
+ (Web Services).
+ </p></item>
+
+ <item><p>
+ <url href="http://www.facebook.com/">Facebook</url>
+ (Facebook chat backend)
+ </p></item>
+
+ <item><p>
+ <url href="http://www.fmi.fi">Finnish Meteorological Institute</url>
+ (Data acquisition and real-time monitoring)
+ </p></item>
+
+ <item><p>
+ <url href="http://www.idt.net">IDT corp.</url>
+ (Real-time least-cost routing expert systems)
+ </p></item>
+ <item><p>
+ <url href="http://www.kreditor.se">Kreditor</url>
+ (Electronic payment systems)
+ </p></item>
+ <item><p>
+ <url href="http://www.mobilearts.se/">Mobilearts</url>
+ (GSM and UMTS services)
+ </p></item>
+ <item><p>
+ <url href="http://www.netkitsolutions.com/">Netkit Solutions</url>
+ (Network Equipment Monitoring and Operations Support Systems)
+ </p></item>
+ <item><p>
+ <url href="http://www.process-one.net/en/">Process-one</url>
+ (Jabber Messaging)
+ </p></item>
+ <item><p>
+ <url href="http://www.schlund.de">Schlund + Partner</url>
+ (Messaging and Interactive Voice Response services)
+ </p></item>
+ <item><p>
+ <url href="http://www.quviq.com">Quviq</url>
+ (Software Test Tool)
+ </p></item>
+ <item><p>
+ <url href="http://www.rabbitmq.com/">RabbitMQ</url>
+ (<url href="http://www.amqp.org/">AMQP</url> Enterprise Messaging)
+ </p></item>
+ <item><p>
+ <url href="http://www.t-mobile.co.uk/">T-Mobile (previously one2one)</url>
+ (advanced call control services)
+ </p></item>
+ <item><p>
+ <url href="http://www.telia.se/">
+ Telia</url> (a telecomms operator)
+ </p></item>
+ <item><p>
+ <url href="http://www.vailsys.com">Vail Systems</url>
+ (Interactive Voice Response systems)
+ </p></item>
+ <item><p>
+ <url href="http://www.wavenet.lk">Wavenet</url>
+ (SS7 and IVR applications)
+ </p></item>
+ </list>
+
+ <p>
+ If you want to be listed here, send me some mail:
+ <url href="mailto:matthias@corelatus.com">
+ matthias@corelatus.com</url>
+ </p>
+</section>
+<section>
+ <marker id="universities"/>
+ <title> Who uses Erlang for research and teaching?</title>
+<p>
+
+ Many universities use Erlang at various levels. This list
+ is far from exhaustive!
+</p>
+
+
+ <list>
+ <item><p>
+ <url href="http://www.ituniv.se/">IT University of Gothenburg</url> in Gothenburg, Sweden
+ </p></item>
+
+ <item><p>
+ <url href="http://www.kth.se/">KTH</url> in Stockholm
+ </p></item>
+
+ <item><p>
+ <url href="http://www.macs.hw.ac.uk/~dsg/telecoms/">
+ Motorola/Heriot-Watt University</url> in the UK.
+ </p></item>
+
+ <item><p>
+ <url href="http://vodka.lfcia.org">University of
+ A Coru&ntilde;a</url> in Spain.
+ </p></item>
+
+ <item><p>
+ <url href="http://www.cem.itesm.mx/">Tecnol&oacute;gica de
+ Monterrey, Campus Estado de M&eacute;xico
+ </url> in the
+ <url href="http://www.arielortiz.com/apps/s200911/tc2006/noticias/">Programming Languages</url> course.
+ </p></item>
+
+ <item><p>
+ <url href="http://www.rmit.edu.au/">The Royal Melbourne
+ Institute of Technology </url>
+ </p></item>
+
+ <item><p>
+ <url href="http://www.uu.se/">Uppsala University </url>
+ in Sweden is home to the
+ <url href="http://www.it.uu.se/research/group/hipe/">HIPE</url>
+ project.
+ </p></item>
+
+ <item><p>
+ <url href="http://www.dcs.shef.ac.uk/~qiang/forse/forse.htm">University of Sheffield</url>
+ </p></item>
+
+ <item><p><url href="https://www.cs.kent.ac.uk/projects/refactor-fp/fp-design/RefactorErlang">The University of Kent</url></p></item>
+
+ </list>
+
+ <p>
+ If you want to be listed here, send me some mail:
+ <url href="mailto:matthias@corelatus.com">
+ matthias@corelatus.com</url>
+ </p>
+
+</section>
+<section><title> Can I get commercial support for Erlang?</title>
+ <p>
+ Several consulting companies provide support and training courses:
+ <url href="http://www.erlang-consulting.com">Erlang-consulting.com
+ </url>,
+ <url href="http://www.erlang-services.com">Sjoland and Thyselius</url> and
+ <url href="http://www.process-one.net/en/services/">Process One</url>.
+ </p>
+
+ <p>
+ Users within Ericsson can obtain support, printed manuals and
+ binaries from <url href="http://www.erlang.se/">www.erlang.se</url>.
+ </p>
+</section>
+</chapter>
196 libraries.xml
@@ -0,0 +1,196 @@
+<?xml version="1.0" encoding="iso-8859-1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+<chapter>
+ <header>
+ <title>Erlang Libraries</title>
+ <prepared>Matthias Lang</prepared>
+<docno></docno>
+<date>2007-09-12</date>
+ <rev>1.0</rev>
+ </header>
+
+<section><title> What's in the OTP libraries?</title>
+<p>
+ The full library descriptions are included with the open-source
+ distribution and also
+ <url href="http://www.erlang.org/doc/">
+ on line</url>. The highlights are:
+</p>
+
+ <section>
+ <title>O&amp;M Support</title>
+ <p>
+ SASL, EVA, INETS and SNMP provide
+ Operations- and maintenance-related functionality:
+ release handling, alarm and event handling,
+ administration via web browser and SNMP.
+ </p>
+
+ </section><section>
+ <title>CORBA</title>
+ <p>
+ ORBER, CosEvent, CosTransactions and IC
+ contain support for everything CORBA related.
+ </p>
+ </section><section>
+ <title>Database</title>
+ <p>
+ Mnesia and Mnemosyne provide a real-time distributed
+ database which can be both in-RAM and on-disk.
+ There is also a standard ODBC client driver.
+ </p>
+ </section><section>
+ <title>ASN.1</title>
+ <p>
+ There is an ASN.1 compiler which produces Erlang code.
+ </p>
+ </section><section>
+ <title>Standard Library</title>
+ <p>
+ A rich collection of modules provides
+ everything from string, list and regular expression
+ manipulation to random number generation and calendar
+ lookups.
+ </p>
+ </section><section>
+ <title>Structural Components</title>
+ <p>
+ gen_server, gen_fsm,
+ and supervision trees provide standard ways of implementing
+ client/server subsystems, state machines and
+ supervised fault-tolerant systems.
+ </p>
+ </section><section>
+ <title>GUI and Graphics</title>
+ <p>
+ gs and webtool provide ways to build a gui.
+ </p>
+ </section>
+
+<p>
+ Among other things, there is also a web server and a GUI interface.
+
+</p></section>
+<section><title> Is there a collection of data structures, e.g. balanced trees?</title>
+<p>
+ Linked lists are a fundamental part of Erlang, as are tuples.
+ The other standard data structures are:
+ </p>
+
+ <table>
+ <row><cell>Module</cell><cell>Description</cell></row>
+ <row><cell>sets</cell>
+ <cell>sets, i.e. a collection of unique elements.</cell>
+ </row>
+ <row><cell>gb_sets</cell>
+ <cell>sets, but based on a general balanced data structure</cell>
+ </row>
+ <row><cell>gb_tree</cell>
+ <cell>a general balanced tree</cell>
+ </row>
+ <row><cell>dict</cell>
+ <cell>maps, also called associative arrays</cell>
+ </row>
+ <row><cell>ets</cell>
+ <cell>hash tables and ordered sets (trees)</cell>
+ </row>
+ <row><cell>dets</cell>
+ <cell>on-disk hash tables</cell>
+ </row>
+ <tcaption>Standard data structures</tcaption>
+ </table>
+
+<p>
+
+ The <url href="http://www.erlang.org/user.html">
+ contributions area</url>
+ at the erlang.org site includes modules for
+ double-ended queues and balanced trees.
+ </p>
+
+ <p>
+ <c>ordset</c> and <c>orddict</c> are
+ not really suitable for large amounts of data: they are no
+ better that lists for many common operations, e.g.
+ inserting an element is O(n) for both. <c>dict</c>
+ and <c>sets</c> are usually preferred.
+ </p><p>
+
+ In practice, Erlang programs use lists (either natively or
+ via <c>dict</c>) for data structures involving