erlang白皮书、用户贡献

Open-source Erlang - White Paper

This is a brief introduction to Erlang for programmers. 


Erlang Overview

Erlang is a programming language which has many features more commonly associated with an operating system than with a programming language: concurrent processes, scheduling, memory management, distribution, networking, etc.

The initial open-source Erlang release contains the implementation of Erlang, as well as a large part of Ericsson's middleware for building distributed high-availability systems.

Erlang is characterized by the following features:

Concurrency - Erlang has extremely lightweight processes whose memory requirements can vary dynamically. Processes have no shared memory and communicate by asynchronous message passing. Erlang supports applications with very large numbers of concurrent processes. No requirements for concurrency are placed on the host operating system.

Distribution - Erlang is designed to be run in a distributed environment. An Erlang virtual machine is called an Erlang node. A distributed Erlang system is a network of Erlang nodes (typically one per processor). An Erlang node can create parallel processes running on other nodes, which perhaps use other operating systems. Processes residing on different nodes communicate in exactly the same was as processes residing on the same node.

Robustness - Erlang has various error detection primitives which can be used to structure fault-tolerant systems. For example, processes can monitor the status and activities of other processes, even if these processes are executing on other nodes. Processes in a distributed system can be configured to fail-over to other nodes in case of failures and automatically migrate back to recovered nodes.

Soft real-time - Erlang supports programming "soft" real-time systems, which require response times in the order of milliseconds. Long garbage collection delays in such systems are unacceptable, so Erlang uses incremental garbage collection techniques.

Hot code upgrade - Many systems cannot be stopped for software maintenance. Erlang allows program code to be changed in a running system. Old code can be phased out and replaced by new code. During the transition, both old code and new code can coexist. It is thus possible to install bug fixes and upgrades in a running system without disturbing its operation.

Incremental code loading - Users can control in detail how code is loaded. In embedded systems, all code is usually loaded at boot time. In development systems, code is loaded when it is needed, even when the system is running. If testing uncovers bugs, only the buggy code need be replaced.

External interfaces - Erlang processes communicate with the outside world using the same message passing mechanism as used between Erlang processes. This mechanism is used for communication with the host operating system and for interaction with programs written in other languages. If required for reasons of efficiency, a special version of this concept allows e.g. C programs to be directly linked into the Erlang runtime system.

Components

Open-source Erlang comes with several standalone components that can be used as building blocks when developing applications. These components understands Erlang's systems messages (load, unload, start, stop, restart, change code).

Inets - HTTP 1.0 server and FTP client.

Mnesia - Distributed real-time database for Erlang. Supports RAM-replication as well as disk storage, allows dynamic schema changes, allows arbitrarily complex data structures to be stored. Mnesia is very fast since it runs in the same address space as the applications that use it - this is possible since both Mnesia and the applications are written in Erlang. Mnesia is a nice example of the power of Erlang: in how many languages could you write a fully-featured industrial-strength distributed DBMS in less than 20,000 lines of code?

Orber - CORBA v2.0 Object Request Broker (ORB).

SNMP - Extensible SNMP v1/v2 agent and MIB compiler.

Tools and Libraries

Open-source Erlang comes with a library of useful tools:

Appmon - Graphical monitoring of process groups (locally and on remote nodes).

ASN.1 - Compile-time and runtime package which supports the ASN.1 Basic Notation and the encoding rules BER, DER and PER (aligned).

Compiler - Erlang compiler.

Debugger - Graphical Erlang debugger.

ERTS - Erlang runtime system, including the virtual machine, the garbage collector, and the port mapper daemon.

GS - Library for writing graphical user interfaces.

IC - Compiler from OMG's Interface Definition Language (IDL) to Erlang and C and Java.

Kernel - C code necessary to run the Erlang system: Erlang built-in functions (BIFs); code, boot and name servers; networking and distribution support; loaders, linkers and loggers; OS and file system interfaces.

Mnemosyne - Optional query language for Mnesia.

Mnesia Session - Foreign languages interface to Mnesia defined in IDL, providing Mnesia access via the IIOP and erl_interface protocols.

OS monitor (OS_MON) - Monitoring of CPU, disk and memory utilization, including SNMP v1/v2 MIBs. Interfaces to Solaris syslogd and Windows NT event log.

Parse tools - LALR-1 parser generator for Erlang (yecc), similar to yacc. Yecc takes a BNF grammar definition as input, and produces Erlang code for a parser as output. Yecc is used to generate the Erlang parser.

PMan - Tool for tracing and viewing the state of Erlang processes (locally or on remote nodes).

SASL - Progress/error/crash report handling, report browsing, release handling, overload regulation.

Stdlib - Libraries for: input/output; incore and disk-based table storage (ETS and DETS); graphs, dictionaries, lists, strings, sets, queues; regular expressions; math. Erlang interpreter, tokenizer, parser, lint and pretty-printer. Generic frameworks for fault-tolerant servers, event handlers, state machines, and process supervisors. Etc, etc.

Table visualizer - Tool for viewing ETS and Mnesia tables.

Toolbar - Simplifies access to the Erlang Tools.

Tools - Coverage analyser, profiler, text-based tracer, Emacs mode, Emacs TAGS file generator, make utility, call graph utility.

Erlang in 14 Examples

The following sections describe the basic features of Erlang through a number of small examples. This is hardly enough to learn the language, so check out the links at the end of this document for suggested further reading.

Sequential Erlang

Example 1 - Factorial

Consider the factorial function n! defined by:

n! = n * (n - 1)!,
n! = 1

if n > 0
if n = 0

The Erlang program for computing factorial closely resembles this definition:

    fac(N) when N > 0  -> N * fac(N-1);
    fac(N) when N == 0 -> 1.

Variables, such as N in this example, start with an uppercase letter (non-numerical constants start with a lowercase letter). In contrast to, for example C variables, Erlang variables can only be assigned once - when a variable has been bound to a value, we cannot bind it to a new value.

This program has two clauses, one for each of the cases (N>0 and N=0). When computing, say, fac(5) we call each of the clauses in order - the first to match the call is selected and executed (the first clause in this case, since 5>0).

We can simplify the second clause to get the program:

    fac(N) when N > 0 ->  N * fac(N-1);
    fac(0)            ->  1.

To understand the simplified second clause, we must understand what is meant by matching a function call with a clause. If we have a function call f(X) and a clause

     f(Y) when Test -> ...

then the call matches the clause if X matches Y and the Test is true. The arguments X and Y match if they are identical or can be made identical by binding variables in Y to corresponding values in X. The call fac(5) matches the first clause, since fac(5) is made identical to fac(N) by binding N to 5 and 5 > 0 is true (but fac(5) does not match the second clause, since it is not identical to fac(0)).

All Erlang functions are defined in modules. A module math containing the factorial function can be written:

    -module(math).
    -export([fac/1]).
 
    fac(N) when N > 0 ->  N * fac(N-1);
    fac(0)            ->  1.

The annotation -export([fac/1]) means the function fac with one argument is exported from the module. Only exported functions can be called from outside the module.

Once a module has been compiled and loaded into the system the query evaluator can be used for function evaluation:

 
mymachine> erl
Erlang (JAM) emulator version 4.7.3
 
Eshell V4.7.3  (abort with ^G)
1> c(math).
{ok,math}
2> math:fac(25).
15511210043330985984000000

As we might guess from the answer of this function evaluation, Erlang can handle arbitrarily large integers without overflow.

Example 2 - Last

Erlang uses the following syntax for linked lists (with three elements in this example): [X,Y,Z]. The notation [First|Rest] means that First is the first element of the list (X in our example) and Rest is the remainder of the list ([Y,Z] in our example). The empty list is denoted [].

This program returns the last element of a list:

 last([First]) -> First;
 last([First|Rest]) -> last(Rest).

The program removes elements from the front of the list until only one element remains (this is the last element of the original list).

Example 3 - Append

This program concatenates two lists:

  append([], List) -> List;
  append([First|Rest], List) -> [First | append(Rest,List)].

The first clause says that concatenating the empty list with any list List yields List.

The second clause says that concatenating [First|Rest] with a list List yeilds a list whose first element is First and whose remainder is the list resulting from concatenating Rest with List.

Note here that the notation [...|...] has different meanings in the function head and function body. In the head it denotes list decomposistion, while in the body it denotes list construction.

Example 4 - Sort

This program sorts a list using the Quicksort algorithm:

  sort([]) -> []; 
  sort([Pivot|T]) -> 
      sort([X||X <- T, X < Pivot]) ++ 
      [Pivot] ++
      sort([X||X <- T, X >= Pivot]).

Here ++ is the infix append operator.

The notation [Expr || Qualifier1, Qualifier2, ...] introduces a list comprehension. Here Expression is an arbitrary expression, and each Qualifier is either a generator or a filter.

For example, the list comprehension

[X || X <- [1,2,a,3,4,b,5,6], integer(X), X > 3].

should be read as:

The list of X such that X is taken from the list [1,2,a,3,4,b,5,6] and X is an integer and X is greater than 3.

Here X <- [1,2,a,3,4,b,5,6] is a generator, and integer(X) and X > 3 are filters. This list comprehension evaluates to [4,5,6].

Example 5 - Adder

Function objects are introduced with the syntax:

  fun(...) -> Expr end

As an example we can write:

  > Adder = fun(N,X) ->  X + N end.
  #Fun
  > Adder(10,5).
  15

As another an example we can write:

  > Adder = fun(N) -> fun(X) -> X + N end end.
  #Fun
  > G = Adder(10).
  #Fun
  > G(5).
  15
Example 5 - Binary Tree

This program looks up a numeric key in a dictionary represented as a binary tree. The value stored with the key is returned. The binary tree is represented as a tuple {Key,Val,Left,Right}, where Left and Right are the left and right subtrees. (Tuples store fixed numbers of arguments, which themselves may be tuples or any other data type).

  lookup(Key, {Key1,Val,Left,Right}) when Key == Key1 ->
      Val;              
  lookup(Key,{Key1,Val,Left,Right}) when Key < Key1 ->
      lookup(Key, Left);
  lookup(Key, {Key1,Val,Left,Right}) when Key > Key1 ->
      lookup(Key, Right).

We can simplify the first clause by replacing Key1 with Key in the head, since Key == Key1 for a call to match this clause (the test Key == Key1 is then redundant):

  lookup(Key, {Key,Val,Left,Right}) ->
      Val;

This works as follows: The first occurrence of Key is bound to an integer n in the call; then the second occurrence - which is now bound to n - is compared to the key in the current root node of the tree. If we have a match, the corresponding value is returned.

(Note also that the test Key > Key1 in the third clause is redundant, since clauses are matched in sequential order. However, it is good programming practice to include it for clarity.)

Concurrent Erlang

Example 6 - An area Server

The next program is an "area server" - you can ask the server what the area of a square or rectangle is, or, you can ask it to return the total of all areas that it has been requested to compute (the total is the local state kept by the server). Messages to the server are tuples {Pid,Request}, where Pid is the client's process identifier.

   -module(area_server).
   -export([start/1, loop/1]).
 
    start() ->
        spawn(area_server, loop, [0]).
 
    loop(Tot) ->
        receive
            {Client, {square, X}} ->
                Client ! X*X,
                loop(Tot + X*X);
            {Client, {rectangle,X,Y}} ->
                Client ! X*Y,
                loop(Tot + X*Y);
            {Client, areas} ->
                Client ! Tot,
                loop(Tot)
        end.

The Erlang primitive spawn(Module,Fun,Args) creates a parallel process which evaluates Module:Fun with arguments from the list Args. It returns a process identifier (Pid) which can be used to communicate with the new process.

The expression Pid ! Msg sends the message Msg to the process Pid. Sending a message is a non-blocking operation. Messages are received using the receive ... end construction, which selects what message to receive by matching the message with the receive clauses in sequential order. The receive operation is blocking - it suspends until a matching message is delivered to the process. This is how synchronization is expressed in Erlang.

Example 7 - An area client

Client code which uses the above server can be written (self() returns the client's Pid):

    Server ! {self(), {square, 10}},
    receive
        Area ->
            Area
    end

Here the area is simply returned from the receive statement.

Example 8 - Named Server

In the above examples, the process identifier of the server had to made known to the client. To provide a named service we can instead register the process under a name, which is local to the node:

    Pid = spawn(Module,Fun,Args),
    register(area_server, Pid)

This associates the name area_server with Pid. Now any process evaluating in the node can send a message to area_server:

    area_server ! SomeMessage

Distribution

Example 9 - Spawning on a remote node

We can start Erlang systems (nodes) on several machines and have them talk to each other. Here is a simple example.

    -module(ex9).
    -export([start/0, world/0]).
    
    start() -> 
        Pid = spawn('b@host2,ex9,world,[]),
        Pid ! {self(), 'hello world!'},
        receive
          Msg ->
            io:format('~w~n',[Msg])
        end.
 
    world() ->
        receive
          {Pid,'hello world!'} ->
            io:format(user,'hello world!~n',[]),          
            Pid ! 'hello, little thread'
        end.

Running the example on two machines yields the following:

host1>erl -sname a

host2>erl -sname b

a@host1>c(ex9).

b@host1>c(ex9).

a@host1>ex9:start().

b@host2>

a@host1>

b@host2>hello, world!

a@host1>hello, little thread

b@host2>

Error detection

Erlang is designed for programming "robust" systems, so there are a number of primitives for trapping errors. Error recovery is not automatic. The programmer must design a fault-tolerant architecture which can be implemented using the error detection mechanisms.

Example 10 - Catch

All Erlang programs run within Erlang processes. If a runtime error occurs in a program, it crashes the process it runs within but leaves other processes intact. So, for example, if you evaluate 1/0 within a process, the process crashes with the printout:

 ** exited: {badarith,{erl_eval,eval_op,['/',1,0]}} **

(In fact, the Erlang shell detects the process crash and prints the message; see Example 13.) A computation Expr can also be enclosed within catch/1, that is we run (catch Expr) instead of just Expr. Any error within Expr is then converted to a data structure describing the error and the process does not crash. Thus (catch 1/0) returns the tuple:

{'EXIT',{badarith,{erl_eval,eval_op,['/',1,0]}}}

Example 11 - Catch and throw

Non-local returns can be performed with throw(Expr), which causes Expr to be evaluated and returned by the enclosing catch. Say that f/1 is a function that may throw an exception:

     f(X) when X > 0 ->
        ...
        NormalReturnValue;
     f(X) when X =< 0 ->
        ...
        throw({exception1, ...}).

In some other part of the program we have a call to f/1, which is wrapped by a catch:

     case catch f(X) of
        {exception1, Why} ->
           handle_exception(Why,...);
        NormalReturnValue ->
           handle_normal_case(NormalReturnValue,...)
     end
Example 12 - Links and trapping exits

Processes can be linked together. If a process dies an error message is sent to all processes to which it is linked and which have set the flag trap_exit.

     process_flag(trap_exit, true),
     Pid = spawn_link(Mod, Fun, Args),
     receive
       {'EXIT', Pid, Why} ->
           handle_process_crash(Why,...);
       ...
     end

Here spawn_link(Mod,Fun,Args) creates a parallel process and links the parent with the child.

Example 13 - Process supervision

If the child process crashes then an error message is sent to all processes which the child process is linked to. In our example an error message is sent to the parent process. The parent process can receive the error message and take appropriate action (for example, restart the child process).

-module(ex13).
-export([start/0, loop/0]).

start() ->
    process_flag(trap_exit, true),
    parent(Child, 5),
    Child = spawn(ex13, child, []).

parent(Child, K) ->
    receive
        {'EXIT', Child, Why} when K > 0 ->
            io:format('child died with reason ~p~n', [Why]),
            NewChild = spawn_link(ex13, child, []),
            parent(NewChild, K-1);
        {'EXIT', Child, _} ->
            io:format('too many restarts, bye~n', [])
    end.

child() -> exit(died).


Program ex13 implements a simple supervisor, which restarts child processes that die. We can easily make Parent supervise Child remotely: just spawn the processes on two separate nodes. The rest of the program is unchanged.

Hot code replacement

Example 14 - Code replacement

Erlang is designed for "non-stop" systems. We need to be able to replace code and data without stopping the system. This example shows how we can change code in a server, without stopping the server.

-module(ex14).
-export([start/0,server/0,client/0]).

start( ) -> Pid = spawn(ex14, server, []), spawn(ex14, client [0,Pid]).

server( ) ->
    receive
        Msg ->
            io:format('received ~p~n', [Msg]),
            ex14:server( )
    end.

client(N, Echo) ->
    Echo ! N,
    client(N+1, Echo).


This example requires that you edit and recompile ex14 while ex14 is running. The recompilation also loads the new code. Once the new module code has been loaded, the next fully qualified call ex14:server() switches to the new version of server().

mymachine> erl
Erlang (JAM) emulator version 4.7.3.3

Eshell V4.7.3.3  (abort with ^G)
> c(ex14).
{ok,ex14}
> ex14:start().        start server() and client(0,Echo_PID)
<0.39.0>
received 0             while ex14 putters along ...
received 1              ... edit ex14 to use "io:format('NEW received ~p~n',[Msg]),"
received 2
received 3
> c(ex14).             compile ex14 again (this loads the new code)
received 4
{ok,ex14}
received 5
NEW received 6         server() has switched to the new code
NEW received 7
NEW received 8
NEW received 9
NEW received 10
>

Applications can also load new code without using the Erlang shell.

Further reading

More links for getting started.

History of this document

Version 1.0 (Joe Armstrong, Bjarne Däcker, Thomas Lindgren, Håkan Millroth): first public version
Version 2.0 (Updates by the Erlang product team at Ericsson)

Erlang Open-Source homepage: http://www.erlang.org
贡献:

One Line Summaries

 

  • ApplicationDate modifiedSummary
    anal-1.0Nov 30, 1998A clever and fast number analyser
    assoc-1.2Nov 30, 1998Associative arrays
    bucket_grid-1.0Jan 27, 2000N-dimensional bucket grid
    byteorder-1.0Feb 17, 1999Test for MSB/LSB byte order.
    ccviewer-1.1Sep 21, 2000Web-based source code browser
    depcheck-1.0Oct 29, 1999A program that checks validity of external references
    deque-1.0Oct 26, 1999Implementation of double ended queues
    diff-1.0Nov 30, 1998Finds the difference between two files
    dispatcher-1.0May 19, 1999A generic method for dispatching dynamic worker threads
    dynarray-1.0Feb 11, 1999Expanding array for heap-based storage
    ehtml-2.0Dec 1, 1998Extended HTML
    email-1.0Nov 30, 1998Send email - parse email - automate email jobs
    epop-2.9Apr 30, 1999A POP3 client/server package
    erlsnoop-1.0Oct 31, 2001A network sniffer for Erlang traffic
    ermake-2.0Dec 1, 1998Make in Erlang
    erpc-0.9Feb 7, 2001Remote Procedure Calls without using Erlang distribution
    esoko-2001.0709Jul 9, 2001Classic puzzle game of Sokoban
    eweb-1.1Aug 30, 2000A system for literate erlang programming
    ex11-0.11Mar 11, 1999An Erlang-X11 binding.
    filesystem-1.0Jan 13, 1999Platform-independent File system operations
    fuz-1.0Dec 13, 1999Simple Fuzzy Logic Evaluator
    gdc-1.0Apr 30, 1999Great Digital Clock, using IG and the curses library.
    gif-1.0Nov 30, 1998Produce GIF pictures from an Erlang program.
    graph_draw-0.0Nov 15, 2001Interactive graphical graph drawing for programs to display there data
    gridfile-1.0Jan 26, 1999Adaptable, Symmetric Multikey File Structure
    gs_dialog-2001.1101Nov 2, 2001Dialog box behaviour for GS
    ibrowse-1.0May 18, 2005 NEW!Powerful HTTP client
    lines-1.1Apr 14, 2000Efficient array of lines (e.g. for text editor)
    locker-1.1Jul 19, 2000Efficient and scalable read-write locker.
    mdisp-1.0Dec 20, 2002A generic method for dispatching dynamic worker threads
    mlex-1.0Oct 21, 2002Lexical scanner.
    nedit_mode-0.9Mar 20, 2000Erlang Nedit mode
    nfs-1.0Sep 13, 2001NFS server
    othello-1.0Nov 30, 1998The Othello game
    parser_tutorial-1.0Nov 30, 1998An example of the use of yecc and leex
    pppgraph-1.0Jun 3, 2000Graphic display of PPP statistics
    prettypr-1.0Sep 8, 2000A generic, flexible pretty printing library.
    property_file-0.1Oct 21, 2002Configuration file parser.
    py_interface-0.92Jul 28, 2004The py_interface is a Python-implementation of an Erlang node.
    ral-1.0Jan 8, 2001Skew-binary random-access lists, ala Chris Okasaki
    rdbms-1.3Jan 3, 2000Relational Database Management System based on mnesia
    reshd-1.2Jul 21, 2002Remote Erlang shell daemon
    rpc-1.1Sep 3, 2001ONC/RPC stub generator and library
    sablotron-1.0Feb 5, 2001Erlang bind for Sablotron, a C++ XSL processor
    safedets-1.0Sep 29, 1999A version of dets that never enters the repair mode
    serial-1.0Nov 18, 1999Serial driver for UNIX.
    service_broker-1.0Oct 21, 1999Brokering and supervision of services
    shbuf-1.1May 15, 2001Erlang server for sharing Emacs buffers & Emacs-Lisp client
    slang-1.0Apr 26, 2001terminal library for Erlang
    smtp_client-1.1Jan 8, 2004Simple SMTP client using gen_fsm behaviour
    stl-1.0Sep 21, 2001Web template processing system.
    syslog-1.0Jan 26, 1999Interface to the Unix syslog facility.
    tdb-0.9Feb 10, 1999TTY interface to the Erlang dubugger.
    timer_mn-1.1Apr 7, 2000Timer for large numbers of concurrent timers.
    top-1.0Apr 30, 1999TOP display information about processes
    trex-2.6Sep 28, 2000A GUI to mnesia and ets.
    ucs-0.3Oct 17, 2002Simple Universal Character Set support (UCS, ISO 10646, Unicode)
    unixdom-0.1Sep 19, 2001A UNIX-domain socket driver
    uue-1.0Nov 30, 1998UUencode and uudecode in plain erlang
    view_backup-1.0Sep 8, 1999Simple program for loading mnesia backup files
    www_tools-1.0Nov 30, 1998Tools for fetching and manipulating WWW pages
    xmerl-0.17Mar 7, 2002XML processing tools
    xml_lt-2.0Nov 6, 2000Verifying XML parser
    xmlrpc-1.13Apr 23, 2003An XML-RPC client/server library
    xx-1.0Nov 30, 1998X number of eXpanding macros

The Programs

 

anal-1.0.tgz - Claes Wikstrom, 
This is a fast number analyser which avoids searching the multiway tree for each access, rather the previous search work is accumulated by means of integer arithmetics

assoc-1.2.tgz - Dan Sahlin, 
Associative arrays with operations for inserting, finding, deleting(including largest and smallest item), combining arrays, stepping through (forwards and backwards), converting to and from lists, map, fold (left and right). Most operations are O(lg n).

bucket_grid-1.0.tgz - Ulf Wiger, 
Implements an N-dimensional bucket storage system. Neighbouring buckets can be split and merged in any dimension, and using any Erlang term as split value; grid traversal and range matching allow for efficient multikey queries. The physical representation is implemented via a callback interface (see example).

byteorder-1.0.tgz - Torbj鰎n T鰎nkvist, 
This little program test whether we are running on a big-endian/little-endian machine. It makes use of a tiny dynamically linked in driver.

ccviewer-1.1.tgz - Ulf Wiger, 
Implements an web-based source code browser. CCviewer is designed to provide a web-based interface to a ClearCase repository of Erlang source code. It provides hypertext linking of source code, and statics cross-references analysis. With modest changes, it should work against other version control systems.

depcheck-1.0.tgz - Peter Andersson, 
Depcheck is a program for finding incorrect module dependencies. Given a source module, it will attempt to locate the dependency modules and validate the function calls. The dependency modules are scanned syntactically, not parsed. (The source module needs to be compilable and is analysed using exref).

deque-1.0.tgz - Claes Wikstr鰉, 
This is an implementation of double ended queues, as described in 'Purely Functional Data structures' by Chris Okasaki

diff-1.0.tgz - Joe Armstrong, 
A diff utilitiy which finds the difference between two files. Unlike unix diff, this version of diff compares the parse trees and not the src text.

dispatcher-1.0.tgz - Ulf Wiger, 
Allows for processes to be dynamically created and 'suspended'. The threads themselves believe that they stay up permanently.Included is a demo program and a gen_server-compatible behaviour.

dynarray-1.0.tgz - Ulf Wiger, 
Implements an efficient dynamically expanding array for heap-based storage. Performance matches that of ets even on relatively small objects. Since it mimics an array, objects are identified via their position (integer) in the array.

ehtml-2.0.tgz - Joe Armstrong, 
This is a macro process which expands extended HTML. Extended HTML is normal HTML with embedded Erlang expressions. The embedded expressions are evaluated and pasted into the resulting document

email-1.0.tgz - Joe Armstrong, 
A number of utilites for manipulating email. The most useful is something which might be described as "send" and "receive" in email,with this you can send and receive Erlang terms as e-mail messages. These programs are *very* useful for building e-mail servers. Read the full docmentation for more details.

epop-2.9.tgz - Torbj鰎n T鰎nkvist, 
Epop is a complete POP3 client/server package implemented according to RFC-1939. Epop also support RFC-2449. With epop it is possible to both store mail as well as read mail. Since epop is compliant with RFC-1939 it is also possible for epop to act either as a client or a server, talking with other POP3 software.

erlsnoop-1.0.tgz - Gordon Beaton, 
Erlsnoop is a simple network sniffer that can identify and display the contents of Erlang messages passing on the network, in a manner similar to tcpdump

ermake-2.0.tgz - Joe Armstrong, 
This is a simple implementation of make in Erlang. This version supports 1) Macros, 2) Include files, 3) suffix rules, and 4) file dependencies

erpc-0.9.tgz - Sean Hinde, 
This provides a socket based multithreaded inter Erlang node Remote Procedure Call mechanism which is independent of the standard Erlang distribution. It provides some security mechanisms, and can optionally be setup to queue calls in the event of a link failure and send them sometime later at a predefined rate while preserving the order of all commands.

esoko-2001.0709.tgz - Chris Pressey, 
This is an Erlang implementation of the challenging puzzle game of Sokoban, where you must push objects towards a goal inside an enclosed space. This version uses GS for display; the puzzle screens are borrowed from the xsokoban distribution.

eweb-1.1.tgz - Joe Armstrong, 
This is a program for literate Erlang programming

ex11-0.11.tgz - Torbj鰎n T鰎nkvist, 
This is an Erlang-X11 binding. Yes, that's right, a binding ! Not another interface to a toolkit. This is the X11 protocol implemented solely in Erlang. The release version indicates how much of the protocol that has been implemented so far (i.e Ver: 0.1 == 10%). However, this package also consists of a complete framework for the protocol implementation, so the rest of the protocol would be very easy to implement. (I estimate that the remaining 90% of the protocol could be implemented in 2-3 weeks). However, before anymore of the protocol is implemented it is suggested that we await the new Erlang bitsyntax. A 'cool' example program comes along with the package. <b>NB: ex11 is the new name and replaces the old name x11</b>.

filesystem-1.0.tgz - Ulf Wiger, 
Implements common filesystem operations in a platform-independent way. (so far only tested on Solaris...)functions: ls(Pattern), find(Dir, Pattern), cwd(), verify_dir(Dir), remove_dir(Dir), set_permission(Mode,Filename)

fuz-1.0.tgz - Ulf Wiger, 
Implements a simple Fuzzy Logic Evaluator. A basic example (Crane Controller) is provided to show how it works. The evaluator seems to perform roughly like a low-cost 8-bit controller when run on a standard workstation. Example Useage: fuz:eval(fuz_crane, control, [Distance, Angle]).

gdc-1.0.tgz - Torbjorn Tornkvist, 
GDC uses the curses library to display a Great Digital Clock. GDC is an example which shows how Erlang can be started by a C program, communicating over an IG generated interface.

gif-1.0.tgz - Joe Armstrong, 
gif.erl provides an interface to gd.1.1.1 a library of C programs which can manipulate GIF images

graph_draw-0.0.tgz - Hans Nilsson, 
This is a set of modules to help programs to graphically present graphs to a person. The person could rearange the graph and the system will keep those positions if the graph is changed by the program.

gridfile-1.0.tgz - Ulf Wiger, 
Implements efficient storage for multikey access. API is similar to ets and dets. Performance is especially good on range queries, where the cost is proportional to the number of objects found - not on the size of the table.

gs_dialog-2001.1101.tgz - Chris Pressey, 
A library application providing an extensible behaviour for dialog boxes under GS, as well as some common dialogs built upon it, including notify, confirm, question, entry, list-select, and color-edit dialogs.

ibrowse-1.0.tgz - Chandrashekhar Mullaparthi, 
A powerful HTTP client written in erlang. Supports HTTP/0.9, HTTP/1.0 and HTTP/1.1

lines-1.1.tgz - Ulf Wiger, 
Implements an efficient array of lines. The lines module allows for efficient manipulation of a dynamic array, where elements can be inserted, modified and deleted anywhere in the array, while an absolute order (e.g. line number) must be maintained. Operations supported are append, insert, insert_after, delete, replace, and of course nth. Even on a large number of elements, access times are in the order <30 microseconds. lines-1.1 fixes a pattern-matching bug in nth/1.

locker-1.1.tgz - Ulf Wiger, 
A read-write locker based on a redundant-master-slave concept. This locker is generally much faster than global -- more so in large networks. Locker nodes are specified as either peers or slaves; one peer is made the master locker (automatically, or manually). All lock negotiation takes place on the master, and lock info is replicated to all the peers (which are standby for the master.) The locker handles both shared and exclusive locks, as well as lock promotion (from shared to exclusive.) This is a slightly modified version of a locker implementation used in the AXD 301 switch. Co-author: Asko Husso <asko.husso@etx.ericsson.se>

mdisp-1.0.tgz - Ulf Wiger, 
Allows for processes to be dynamically created and 'suspended'. The threads themselves believe that they stay up permanently. Mdisp replaces dispatcher-1.0. The two are not compatible. Mdisp offers a cleaner interface and better performance.

mlex-1.0.tgz - Vladimir Sekissov, 
MLex is a simple lexical scanner.It supports mostly all frequently used lex regexps, predictive operator, long (default) and short regexps.

nedit_mode-0.9.tgz - Daniel Solaz, 
Erlang syntax highlighting mode for Nedit 5.

nfs-1.0.tgz - Luke Gorrie, 
Extensible, minimal NFS v2 server. Includes a "/proc" example filesystem.

othello-1.0.tgz - Magnus Fr鯾erg, Torbj鰎n T鰎nkvist, 
This is an implementation of the game Othello. Take a break, relax your brain, and have some fun trying to beat the computer in a game of Othello

parser_tutorial-1.0.tgz - Joe Armstrong, 
This is an example of making a parser using the standard tools yecc (which is a yacc lookalike) and leex (which is a lex lookalike). A parser for a simple language is constructed

pppgraph-1.0.tgz - Lars Bjornfot, 
Display receive and transmit rates in byte/s, updated every second. Need pppstats(8). Runs on at least Red Hat Linux.

prettypr-1.0.tgz - Richard Carlsson, 
The `prettypr' module provides a powerful library of functions for flexible, generic and fast pretty printing.

property_file-0.1.tgz - Vladimir Sekissov, 
This is configuration files parser.It is property_lists module compliant and supports two popular configuration formats, Apache and C-like,property substitution and file inclusion. It works with Unix, DOS and Mac files.

py_interface-0.92.tgz - Tomas Abrahamsson, 
The py_interface provides the possibility to run a python node that may be used for communication with other Erlang nodes. This release contains bugfixes for packing/unpacking of terms on the python side.

ral-1.0.tgz - Lon Willett, 
This is an implementation of skew-binary random-access lists, as described Chris Okasaki (see reference at start of source). It also provides many useful supporting functions (mostly clones of the lists module functions).

rdbms-1.3.tgz - Ulf Wiger, 
Adds relational constraints checking to mnesia. Also included is a modular data import tool. This version of RDBMS has been tested to work on OTP R6B (mnesia-3.8). Also, a bug concerning commit- and rollback triggers has been fixed. Minor bug fixes since 1.2 -- see the README file.

reshd-1.2.tgz - Tomas Abrahamsson, 
Reshd stands for remote Erlang shell daemon. It offers a telnet port into an Erlang shell in the Erlang node.

rpc-1.1.tgz - Tony Rogvall, Scott Fritchie, Jim Larson, Martin Bjorklund, 
This is a stub generator for the ONC/RPC protocol. Given a protocol specification in the RPC syntax (RFC1831), the stub generator will create client-side and server-side code for encoding and decoding procedure calls into XDR-encoded network messages. Version 1.1 is rewritten for R7 - faster XDR routines which generates less garbage.

sablotron-1.0.tgz - Victor M. Gulias, 
This is an adapter for a C++ XSL processor (sablotron) that allows Erlang programmers to perform transformations of XML data (binary or file) using an XSL stylesheet (binary or file)

safedets-1.0.tgz - Claes Wikstrom, 
This module xports exactly the same interface as the original dets module in erlang 47.4.1 with the exceptio that the {ok, Handle} that is returned by the open_file/2 function can only be used by the the process that issued the open_file/2 The idea here is to use two dets files instead of one All write ops go into one dets file as well as into a log. Whenever ?WRITE_THRESHOLD write ops have been done, the log is transfered into the second dets file **while** the original dets file is closed. This way we get dets files that can be opened for writing at runtime and they will never be subject to repair. This means that we can have very very large dets files. The time to repair a dets file with say 1.000.000 objects in it can be very large, maybe upto 12 hours which typically is not acceptable . the downside is that that write ops take more than twice the time (in mean) to execute as well the file space which is doubled.

serial-1.0.tgz - Johan Bevemyr, 
This is a port program with erlang driver for serial communication.

service_broker-1.0.tgz - Hakan Mattsson, 
Brokering and supervision of services for service providers and their users. When either part of the service dies or selects to disconnect from the service, the other part is notified about this. The service broker may be for many purposes, such as dynamic syncronizing of application startup, protocol negotiations, inter application supervision, implementation of safe calls etc. A man page (as comment in the module) and test program are also supplied.

shbuf-1.1.tgz - Luke Gorrie, 
An Erlang server for sharing Emacs buffers across the network. Includes: Erlang server, Erlang data structure for large buffers of text, Emacs client library for Erlang external term format, and an Emacs client for the sharing server.

slang-1.0.tgz - Claes Wikstrom, 
This is a library which makes it possible to write terminal based aplications al'a vi/emacs/mutt/slrn in erlang.

smtp_client-1.1.tgz - Michael Bradford, 
A simple SMTP client using gen_fsm behaviour. Supports basic SMTP & ESMTP commands, including MD5, plain & login authentication. This version fixes a minor bug in v1.0 (see source code for details). Also included is email_msg.erl. This very simple module builds a plain text email suitable for sending via the smtp client.

stl-1.0.tgz - Vladimir Sekissov, 
STL as `Simple Template Language' is a clone of Bruce R. Lewis's BRL (http://brl.sourceforge.net) implemented in Erlang. It deals with template processing and has most capabilities which user expects from web template engines.

syslog-1.0.tgz - Torbjorn Tornkvist, 
This is a simple interface to the Unix syslog facility.

tdb-0.9.tgz - Torbjorn Tornkvist, 
If you don't like cluttering your screen with windows, or if you do/can not use a window system, then this TTY interface for the Erlang debugger may be something for you. With this interface you can do almost anything you can do with the X-based interface.

timer_mn-1.1.tgz - Sean Hinde, 
This application re-implements the standard timer module towork for very large numbers of concurrent timers.This implementation uses an mnesia ordered_set table to holdthe timers, which is much more scaleable than the ordered listused in the standard timer module.

top-1.0.tgz - Torbjorn Tornkvist, 
somewhat similar to Unix top. This programs displays information about the running Erlang processes in you system. The output can be customized in various way to be sorted on for example number of reductions made since last call or change in heap size since lats call, etc...

trex-2.6.tgz - Leif Lorentzen, 
This is a Graphical User Interface which make it easy to explore mnesia and ets tables. With trex you can read, write and search in mnesia/ets tables, dump the tables to a file and look at it off-line, log updates to mnesia tables for debugging purposes, among other things.

ucs-0.3.tgz - Lon Willett, 
This module provides some basic support for decoding, encoding, and handling ISO 10646 character strings (Universal Character Set strings, aka Unicode, sort of). See the file ucs.doc for details. The latest version can be found at http://sowap.sourceforge.net/

unixdom-0.1.tgz - Scott Lystig Fritchie, 
This is an incomplete implementation of a UNIX-domain socket driver for the Erlang VM. It was originally written while I was at Sendmail, Inc. All of the major functions work, though the timeout-handling code is probably flaky. Under Solaris/SPARC, we saw roughly a 10% improvement in bulk data throughput using this driver versus using TCP across the loopback interface.

uue-1.0.tgz - Joe Armstrong, 
UUencode and uudeocde written i plain Erlang. This is useful if you want to write portable applications.

view_backup-1.0.tgz - Ulf Wiger, 
Simple program for loading a mnesia backup file into memory. API: view_backup:file("Filename") -> ok. The function loads mnesia data into ets tables with the same names as the corresp. mnesia tables. Table definitions are put in the table 'SCHEMA'. The result may be viewed with e.g. table visualiser or trex.

www_tools-1.0.tgz - Joe Armstrong, 
WWW tools is a package of tools for fetching and manipulating web pages. The programs in this package illustrate how to fetch a URL using the Erlang socket interface, we show how to tokenise and analysis HTML and also provide a simple macro processor for HTML.

xmerl-0.17.tgz - Ulf Wiger, Johan Blom, Richard Carlsson, Mickael Remond, 
Implements a set of tools for processing XML documents, as well as working with XML-like structures in Erlang. The main attraction so far is a single-pass, highly customizable XML processor. Other components are an export/translation facility and an XPATH query engine. This version fixes a few bugs in the scanner, and improves HTML export. The latest version can be found at http://sowap.sourceforge.net/ Note that this is still very much a beta product.

xml_lt-2.0.tgz - Joe Armstrong, 
Yet another XML parser. This is an interface to the Edinburgh LT XML toolkit

xmlrpc-1.13.tgz - Joakim Greben�, 
This is an HTTP 1.1 compliant XML-RPC library for Erlang. It is designed to make it easy to write XML-RPC Erlang clients and/or servers. The library is compliant with the XML-RPC specification published by http://www.xmlrpc.org/.

xx-1.0.tgz - Torbj鰎n T鰎nkvist, 
This module uses parse transformations to define a couple of useful Erlang macros, e.g unique variables within another macro definition.

 

  

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值