Erlang (programming language)
From Wikipedia, the free encyclopedia
Paradigm | multi-paradigm: concurrent, functional |
---|---|
Appeared in | 1987 |
Designed by | Ericsson |
Developer | Ericsson |
Typing discipline | dynamic, strong |
Major implementations | Erlang |
Influenced by | Prolog |
Influenced | Clojure, Scala |
License | Modified MPL |
Erlang Programming at Wikibooks |
Erlang is a general-purpose concurrent programming language and runtime system. The sequential subset of Erlang is a functional language, with strict evaluation, single assignment, and dynamic typing. For concurrency it follows the Actor model. It was designed by Ericsson to support distributed, fault-tolerant, soft-real-time, non-stop applications. The first version was designed and implemented by Joe Armstrong in 1986.[1] It supports hot swapping so code can be changed without stopping a system.[2] Erlang was originally a proprietary language within Ericsson, but was released as open source in 1998. The Ericsson implementation primarily runs interpreted virtual machine code, but it also includes a native code compiler (supported on most but not all platforms), developed by the High Performance Erlang Project (HiPE) [3] at Uppsala University. It also now supports interpretation via script as of R11B-5.
Creating and managing processes is trivial in Erlang, whereas threads are considered a complicated and error-prone topic in most languages. Though all concurrency is explicit in Erlang, processes communicate using message passing instead of shared variables, which removes the need for locks.
Erlang is named after A. K. Erlang. It is sometimes thought that its name is an abbreviation of Ericsson Language, owing to its origin inside Ericsson. According to Bjarne Däcker, who headed the Computer Science Lab at the time, this duality is intentional.[4]
Contents |
[edit] Functional language
A factorial algorithm implemented in Erlang:
-module(fact). % This is the file 'fact.erl', the module and the filename MUST match -export([fac/1]). % This exports the function 'fac' of arity 1 (1 parameter, no type, no name) fac(0) -> 1; % If 0, then return 1, otherwise (note the semicolon ; meaning 'else') fac(N) -> N * fac(N-1). % Recursively determine, then return the result % (note the period . meaning 'endif' or 'function end')
A quicksort algorithm implementation:
%% quicksort:quicksort(List) %% Sort a list of items -module(quicksort). % This is the file 'quicksort.erl' -export([quicksort/1]). % A function 'quicksort' with 1 parameter is exported (no type, no name) quicksort([]) -> []; % If the list [] is empty, return an empty list (nothing to sort) quicksort([Pivot|Rest]) -> % Compose recursively a list with 'Front' % from 'Pivot' and 'Back' from 'Rest' quicksort([Front || Front <- Rest, Front < Pivot]) ++ [Pivot] ++ quicksort([Back || Back <- Rest, Back >= Pivot]).
The above example recursively invokes the function quicksort
until nothing remains to be sorted. The expression [Front || Front <- Rest, Front < Pivot]
is a list comprehension, meaning “Construct a list of elements Front
such that Front
is a member of Rest
and Front
is less than Pivot
”.
A compare function can be used, however, if the order on which Erlang bases its return value (true
or false
) needs to be changed. If, for example, we want an ordered list where a < 1
evaluates true
.
The following code would sort lists according to length:
% This is file 'listsort.erl' (the compiler is made this way) -module(listsort). % Export 'by_length' with 1 parameter (don't care of the type and name) -export([by_length/1]). by_length(Lists) -> % Use 'qsort/2' and provides an anonymous function as parameter (!!!) qsort(Lists, fun(A,B) when is_list(A), is_list(B) -> length(A) < length(B) end). qsort([], _)-> []; % If list is empty, return an empty list (discard the second parameter) qsort([Pivot|Rest], Smaller) -> qsort([X || X <- Rest, Smaller(X,Pivot)], Smaller) % Concatenate 'X' from 'Rest' ++ [Pivot] ++ % Use the anonymous fun (here named 'Smaller') to test the 'Pivot' qsort([Y ||Y <- Rest, not(Smaller(Y, Pivot))], Smaller). % Concatenate 'Y' from 'Rest'
[edit] Concurrency and distribution oriented language
Erlang's main strength is support for concurrency. It has a small but powerful set of primitives to create processes and communicate between them. Processes are the primary means to structure an Erlang application. Erlang processes are neither operating system processes nor operating system threads, but lightweight processes somewhat similar to Java's original “green threads” (the Java Virtual Machine now uses native threads). Like operating system processes (and unlike green threads and operating system threads) they have no shared state between them. The estimated minimal overhead for each is 300 words (4 bytes per word on 32-bit platforms, 8 bytes per word on 64-bit platforms), so many of them can be created without degrading performance (a benchmark with 20 million processes was tried[5]). Erlang has supported symmetric multiprocessing since release R11B of May 2006.
Process communication is done via a shared-nothing asynchronous message passing system: every process has a “mailbox”, a queue of messages sent by other processes, that are not yet consumed. A process uses the receive
primitive to retrieve messages that match desired patterns. A message-handling routine tests messages in turn against each pattern, until one of them matches. When the message is consumed (removed from the mailbox) the process resumes execution. A message may comprise any Erlang structure, including primitives (integers, floats, characters, atoms), tuples, lists, and functions.
Code examples:
% create process and call the function web:start_server(Port, MaxConnections) ServerProcess = spawn (web, start_server, [Port, MaxConnections]), % create a remote process and call the function web:start_server(Port, MaxConnections) on % machine RemoteNode RemoteProcess = spawn(RemoteNode, web, start_server, [Port, MaxConnections]), % send the {pause, 10} message (a tuple with an atom "pause" and a number "10") to % ServerProcess (asynchronously) ServerProcess ! {pause, 10}, % receive messages sent to this process receive a_message -> do_something; {data, DataContent} -> handle(DataContent); {hello, Text} -> io:format("Got hello message: ~s", [Text]); {goodbye, Text} -> io:format("Got goodbye message: ~s", [Text]) end.
As the example shows, there is built-in support for distributed processes. Processes may be created on remote nodes, and communication with them is transparent (i.e. the communication with remote processes is done exactly as the communication with local processes).
Concurrency supports the primary method of error-handling in Erlang. When a process crashes, it neatly exits and sends a message to the controlling process which can take action. This way of error handling may increase maintainability and reduce complexity of code.
[edit] Hot code loading and modules
Code is loaded and managed as "module" units, the module is a compilation unit. The system can keep two versions of a module in memory at the same time, and processes can concurrently run code from each. The versions are referred to the "new" and the "old" version. A process will not move into the new version until it makes an external call to its module.
An example of the mechanism of hot code loading:
%% A process whose only job is to keep a counter. %% First version -module(counter). -export([start/0, codeswitch/1]). start() -> loop(0). loop(Sum) -> receive {increment, Count} -> loop(Sum+Count); {counter, Pid} -> Pid ! {counter, Sum}, loop(Sum); code_switch -> ?MODULE:codeswitch(Sum) % Force the use of 'codeswitch/1' from the latest MODULE version end. codeswitch(Sum) -> loop(Sum).
For the second version, we add the possibility to reset the count to zero.
%% Second version -module(counter). -export([start/0, codeswitch/1]). start() -> loop(0). loop(Sum) -> receive {increment, Count} -> loop(Sum+Count); reset -> loop(0); {counter, Pid} -> Pid ! {counter, Sum}, loop(Sum); code_switch -> ?MODULE:codeswitch(Sum) end. codeswitch(Sum) -> loop(Sum).
Only when receiving a message consisting of the atom 'code_switch' will the loop execute an external call to codeswitch/1 (?MODULE is a preprocessor macro for the current module). If there is a new version of the "counter" module in memory, then its codeswitch/1 function will be called. The practice of having a specific entry-point into a new version allows the programmer to transform state to what is required in the newer version. In our example we keep the state as an integer.
In practice systems are built up using design principles from the Open Telecom Platform which leads to more code upgradable designs. Successful hot code loading is a tricky subject, code needs to be written to make use of Erlang's facilities.
[edit] Distribution
Erlang was released by Ericsson as open-source to ensure its independence from a single vendor and to increase awareness of the language. Distribution of the language together with libraries and the real-time distributed database Mnesia is the Open Telecom Platform (OTP) collection of libraries. Ericsson and a few other companies offer commercial support for Erlang.
Since it was released as open source in 1998 it has been used by several companies worldwide, including Nortel and T-Mobile.[6] Although Erlang was designed to fill a niche and has remained an obscure language for most of its existence, it is experiencing increase in popularity due to increased demand for concurrent services.[7][8]
Among projects using Erlang are ejabberd - an XMPP instant messaging server, Wings 3D - 3D modeller written, Yaws (Yet Another Web Server), Nitrogen - an event-driven web framework with support for Web 2.0 features, Amazon SimpleDB,[9] Yahoo! Delicious,[10] and the Facebook Chat system. [11]
As of 2008[update], Erlang is under active development with regular releases. It is available for several Unix-like operating systems (including Mac OS X) and also Microsoft Windows.
[edit] Clones
Erlang has inspired several clones of its concurrency facilities for other languages:
- C#: Retlang
- Python: Candygram
- JavaScript: Er.js
- Lisp: Termite Scheme, erlang-in-lisp, CL-MUPROC, Distel
- PHP: PHP/Erlang
- Ruby: Erlectricity
- Scala
- Reia
[edit] Notes
- ^ About the Author
- ^ Joe Armstrong, Bjarne Däcker, Thomas Lindgren, Håkan Millroth. "Open-source Erlang - White Paper". http://erlang.org/white_paper.html. Retrieved on 2008-01-23.
- ^ "High Performance Erlang". http://www.it.uu.se/research/group/hipe/. Retrieved on 2008-03-23.
- ^ Erlang, the mathematician?
- ^ Ulf Wiger (2005-11-14). "Stress-testing erlang". comp.lang.functional.misc. http://groups.google.com/group/comp.lang.functional/msg/33b7a62afb727a4f?dmode=source. Retrieved on 2006-08-25.
- ^ "Who uses Erlang for product development?". Frequently asked questions about Erlang. http://www.erlang.org/faq/faq.html#AEN50. Retrieved on 2007-07-16. "The largest user of Erlang is (surprise!) Ericsson. Ericsson use it to write software used in telecommunications systems. Many (dozens) projects have used it, a particularly large one is the extremely scalable AXD301 ATM switch. Other commercial users listed as part of the FAQ include: Nortel, Deutsche Flugsicherung (the German national air traffic control organisation), and T-Mobile."
- ^ "Programming Erlang". http://www.ddj.com/linux-open-source/201001928?cid=RSSfeed_DDJ_OpenSource. Retrieved on 2008-12-13. "Virtually all language use shared state concurrency. This is very difficult and leads to terrible problems when you handle failure and scale up the system...Some pretty fast-moving startups in the financial world have latched onto Erlang; for example, the Swedish www.kreditor.se."
- ^ "Erlang, the next Java". http://www.cincomsmalltalk.com/userblogs/ralph/blogView?showComments=true&entry=3364027251. Retrieved on 2008-10-08. "I do not believe that other languages can catch up with Erlang anytime soon. It will be easy for them to add language features to be like Erlang. It will take a long time for them to build such a high-quality VM and the mature libraries for concurrency and reliability. So, Erlang is poised for success. If you want to build a multicore application in the next few years, you should look at Erlang."
- ^ http://www.satine.org/archives/2007/12/13/amazon-simpledb/
- ^ http://blog.socklabs.com/2008/09/erlang_is_delicious_cufp_slide
- ^ http://www.facebook.com/note.php?note_id=16787213919&id=9445547199&index=2
[edit] Further reading
- Joe Armstrong (2003). Making reliable distributed systems in the presence of software errors. Ph.D. Dissertation. The Royal Institute of Technology, Stockholm, Sweden. http://www.sics.se/~joe/thesis/armstrong_thesis_2003.pdf.
- Joe Armstrong (Pragmatic Bookshelf, 2007, ISBN 978-1-9343560-0-5). “Programming Erlang, Software for a Concurrent World”.
- Mattsson, H., Nilsson, H., Wikstrom, C.: “Mnesia - A distributed robust DBMS for telecommunications applications.” First International Workshop on Practical Aspects of Declarative Languages (PADL'99) (1999) pages 152-163
- J. Armstrong, R. Virding, C. Wikström, M. Williams (Prentice Hall, 1996, ISBN 0-13-508301-X) "Concurrent Programming in Erlang"
- Martin Logan, Eric Merritt, Richard Carlsson, and Robert Calco (Manning MEAP, 2008, ISBN 1933988789) "Concurrent Programming with Erlang/OTP"
[edit] External links
Wikibooks has a book on the topic of |
- Open Source Erlang website
[edit] History
- Early history of Erlang (by Bjarne Däcker)
- A History of Erlang (by Joe Armstrong)
- Erlang: The Movie (google video) (high quality version)
[edit] Websites and directories
- Erlang at the Open Directory Project
- trapexit - Erlang community site
- CEAN The Comprehensive Erlang Archive Network