**Erlang** (/ˈɜːrlæŋ/ *UR-lang*) là ngôn ngữ lập trình đa năng, đồng thời, là ngôn ngữ lập trình hàm, và là một hệ thống thu gom rác được phát triển tại Phòng thí nghiệm Khoa học Máy tính của Ericsson. OTP (Nền tảng viễn thông mở) là một tập hợp các thư viện và phần mềm trung gian trong Erlang. Erlang / OTP đã được thử nghiệm trong một số sản phẩm của Ericsson để xây dựng các ứng dụng phân tán chịu lỗi mạnh mẽ, ví dụ AXD301 (công tắc ATM). Erlang / OTP hiện được duy trì bởi đơn vị Erlang / OTP tại Ericsson.

Nó cung cấp sự thay đổi nóng của mã để có thể thay đổi mà không cần dừng hệ thống. Ban đầu nó là phần mềm độc quyền trong Ericsson, được phát triển bởi Joe Armstrong, Robert Virding và Mike Williams vào năm 1986, nhưng nó được cho mượn dưới dạng phần mềm nguồn mở vào năm 1998. Việc triển khai của Ericsson chủ yếu được diễn giải, nhưng nó cũng bao gồm trình biên dịch HiPE (chỉ được hỗ trợ trên một số nền tảng).

Việc tạo, quản lý và giao tiếp các quy trình rất đơn giản trong Erlang, trong khi ở nhiều ngôn ngữ, các luồng được coi là một phần phức tạp và dễ bị lỗi. Trong Erlang tất cả sự đồng tình là rõ ràng.

Erlang nhận được tên của A. K. Erlang. Đôi khi người ta cho rằng tên này là tên viết tắt của ERicsson LANGuage, do được sử dụng nhiều trong Ericsson. Theo Bjarne Däcker - người đứng đầu Phòng thí nghiệm Khoa học Máy tính vào thời điểm đó - sự đối ngẫu này là có chủ ý.

Một trong những sản phẩm công nghệ nổi bật sử dụng công nghệ Erlang là WhatsApp được phát triển bởiJan Koum, Brian Acton năm 2009 và được Facebook mua lại năm 2014 với giá trị 19 tỷ USD

OTP
---

OTP được thiết lập các thư viện Erlang và các nguyên tắc thiết kế cung cấp kho trung gian để phát triển các hệ thống này. Nó bao gồm cơ sở dữ liệu phân tán của riêng mình, các ứng dụng để giao tiếp với các ngôn ngữ khác, gỡ lỗi và phát hành các công cụ xử lý.

Ví dụ về lập trình hàm
----------------------

### Tính giai thừa

```
-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) when N > 0, is\_integer(N) -> N \* fac(N-1).
% Recursively determine, then return the result
% (note the period. meaning 'endif' or 'function end')
%% This function will crash if anything other than a nonnegative integer is given.
%% It illustrates the "Let it crash" philosophy of Erlang.

```

### Dãy Fibonacci

Thuật toán đệ quy đuôi tạo ra Dãy Fibonacci:

```
%% The module declaration must match the file name "series.erl" 
-module(series).

%% The export statement contains a list of all those functions that form
%% the module's public API. In this case, this module exposes a single
%% function called fib that takes 1 argument (I.E. has an arity of 1)
%% The general syntax for -export is a list containing the name and
%% arity of each public function
-export([fib/1]).

%% ---------------------------------------------------------------------
%% Public API
%% ---------------------------------------------------------------------

%% Handle cases in which fib/1 receives specific values
%% The order in which these function signatures are declared is a vital
%% part of this module's functionality

%% If fib/1 is passed precisely the integer 0, then return 0
fib(0) -> 0;

%% If fib/1 receives a negative number, then return the atom err\_neg\_val
%% Normally, such defensive coding is discouraged due to Erlang's 'Let
%% it Crash' philosophy; however, in this case we should explicitly
%% prevent a situation that will crash Erlang's runtime engine
fib(N) when N < 0 -> err\_neg\_val;

%% If fib/1 is passed an integer less than 3, then return 1
%% The preceding two function signatures handle all cases where N < 1,
%% so this function signature handles cases where N = 1 or N = 2
fib(N) when N < 3 -> 1;

%% For all other values, call the private function fib\_int/3 to perform
%% the calculation
fib(N) -> fib\_int(N, 0, 1).

%% ---------------------------------------------------------------------
%% Private API
%% ---------------------------------------------------------------------

%% If fib\_int/3 receives a 1 as its first argument, then we're done, so
%% return the value in argument B. Since we are not interested in the
%% value of the second argument, we denote this using \_ to indicate a
%% "don't care" value
fib\_int(1, \_, B) -> B;

%% For all other argument combinations, recursively call fib\_int/3
%% where each call does the following:
%% - decrement counter N
%% - Take the previous fibonacci value in argument B and pass it as
%% argument A
%% - Calculate the value of the current fibonacci number and pass it
%% as argument B
fib\_int(N, A, B) -> fib\_int(N-1, B, A+B).

```

Chương trình tương tự mà không có nhận xét giải thích:

```
-module(series).
-export([fib/1]).

fib(0) -> 0;
fib(N) when N < 0 -> err\_neg\_val;
fib(N) when N < 3 -> 1;
fib(N) -> fib\_int(N, 0, 1).

fib\_int(1, \_, B) -> B;
fib\_int(N, A, B) -> fib\_int(N-1, B, A+B).

```

### Quicksort

Quicksort trong Erlang, sử dụng danh sách hiểu:

```
%% qsort:qsort(List)
%% Sort a list of items
-module(qsort). % This is the file 'qsort.erl'
-export([qsort/1]). % A function 'qsort' with 1 parameter is exported (no type, no name)

qsort([]) -> []; % If the list [] is empty, return an empty list (nothing to sort)
qsort([Pivot|Rest]) ->
 % Compose recursively a list with 'Front' for all elements that should be before 'Pivot'
 % then 'Pivot' then 'Back' for all elements that should be after 'Pivot'
 qsort([Front || Front <- Rest, Front < Pivot]) ++ 
 [Pivot] ++
 qsort([Back || Back <- Rest, Back >= Pivot]).

```
Ví dụ trên gọi đệ quy hàm `qsort` cho đến khi không còn gì để sắp xếp. Biểu thức `[Front || Front <- Rest, Front < Pivot]` là một danh sách hiểu, nghĩa là "Xây dựng một danh sách các phần tử `Front` sao cho `Front` là một phần tử của `Rest`, và `Front` nhỏ hơn `Pivot`." `++` là toán tử nối danh sách.

Hàm so sánh có thể được sử dụng cho các cấu trúc phức tạp hơn để dễ đọc.

Đoạn code sau sẽ sắp xếp danh sách theo độ dài:

```
% This is file 'listsort.erl' (the compiler is made this way)
-module(listsort).
% Export 'by\_length' with 1 parameter (don't care about the type and name)
-export([by\_length/1]).

by\_length(Lists) -> % Use 'qsort/2' and provides an anonymous function as a parameter
 qsort(Lists, fun(A,B) -> length(A) < length(B) end).

qsort([], \_)-> []; % If list is empty, return an empty list (ignore the second parameter)
qsort([Pivot|Rest], Smaller) ->
 % Partition list with 'Smaller' elements in front of 'Pivot' and not-'Smaller' elements
 % after 'Pivot' and sort the sublists.
 qsort([X || X <- Rest, Smaller(X,Pivot)], Smaller)
 ++ [Pivot] ++
 qsort([Y || Y <- Rest, not(Smaller(Y, Pivot))], Smaller).

```
Một `Pivot` lấy từ phần tử đầu tiên sẽ được cấp cho `qsort()` và phần còn lại của `Lists` được đặt tên là `Rest`. Lưu ý rằng biểu thức

```
[X || X <- Rest, Smaller(X,Pivot)]

```
không khác gì biểu thức dưới đây về hình thức

```
[Front || Front <- Rest, Front < Pivot]

```
ngoại trừ việc sử dụng hàm so sánh trong phần cuối. Biểu thức trên có thể diễn đạt là "Xây dựng danh sách các phần tử `X` sao cho `X` là một phần tử của `Rest`, và `Smaller` thì đúng", với `Smaller` được định nghĩa trước đó là:

```
fun(A,B) -> length(A) < length(B) end

```
Hàm ẩn danh được đặt tên là `Smaller` trong danh sách tham số của định nghĩa thứ hai của `qsort` để nó có thể được tham chiếu bởi tên đó trong hàm đó. Nó không được đặt tên trong định nghĩa đầu tiên của `qsort`.

Kiểu dữ liệu
------------

Erlang có 8 kiểu dữ liệu cơ bản:

* Integers:
* Atoms:
* Floats
* References
* Binaries
* Pids
* Ports
* Funs

3 kiểu dữ liệu phức hợp:

* Tuples
* Lists
* Maps

và 2 Cú pháp đặc biệt được cung cấp:

* Strings
* Records

Tham khảo
---------

1. ↑  "Releases - erlang/otp". Truy cập ngày 27 tháng 11 năm 2020 – qua GitHub.
2. ↑  Conferences, N. D. C. (ngày 4 tháng 6 năm 2014). "Joe Armstrong - Functional Programming the Long Road to Enlightenment: a Historical and Personal Narrative". Vimeo.
3. ↑  "Erlang – Introduction". *erlang.org*.
4. ↑  Armstrong, Joe (2007). *History of Erlang*. *HOPL III: Proceedings of the third ACM SIGPLAN conference on History of programming languages*. ISBN 978-1-59593-766-7.
5. ↑  "How tech giants spread open source programming love - CIO.com". Bản gốc lưu trữ ngày 22 tháng 2 năm 2019. Truy cập ngày 30 tháng 11 năm 2020.
6. ↑  "Erlang/OTP Released as Open Source, 1998-12-08". Bản gốc lưu trữ ngày 9 tháng 10 năm 1999.
7. ↑  "Erlang – List Comprehensions". *erlang.org*.

Đọc thêm
--------

* Armstrong, Joe (2003). "Making reliable distributed systems in the presence of software errors" (PDF). PhD Dissertation. The Royal Institute of Technology, Stockholm, Sweden. Lưu trữ bản gốc ngày 23 tháng 3 năm 2015. Truy cập ngày 13 tháng 2 năm 2016. Chú thích journal cần `|journal=` (trợ giúp)Quản lý CS1: bot: trạng thái URL ban đầu không rõ (liên kết)
* Armstrong, Joe (2007). "A history of Erlang". *Proceedings of the third ACM SIGPLAN conference on History of programming languages – HOPL III*. tr. 6–1. doi:10.1145/1238844.1238850. ISBN 978-1-59593-766-7.
* Early history of Erlang Lưu trữ 2019-08-29 tại Wayback Machine by Bjarne Däcker
* Mattsson, H.; Nilsson, H.; Wikstrom, C. (1999). "Mnesia – A distributed robust DBMS for telecommunications applications". *First International Workshop on Practical Aspects of Declarative Languages (PADL '99)*: 152–163.
* Armstrong, Joe; Virding, Robert; Williams, Mike; Wikstrom, Claes (ngày 16 tháng 1 năm 1996). *Concurrent Programming in Erlang* (ấn bản 2). Prentice Hall. tr. 358. ISBN 978-0-13-508301-7. Bản gốc lưu trữ ngày 6 tháng 3 năm 2012.
* Armstrong, Joe (ngày 11 tháng 7 năm 2007). *Programming Erlang: Software for a Concurrent World* (ấn bản 1). The Pragmatic Programmer. tr. 536. ISBN 978-1-934356-00-5.
* Thompson, Simon J.; Cesarini, Francesco (ngày 19 tháng 6 năm 2009). *Erlang Programming: A Concurrent Approach to Software Development* (ấn bản 1). Sebastopol, California: O'Reilly Media, Inc. tr. 496. ISBN 978-0-596-51818-9. Bản gốc lưu trữ ngày 16 tháng 10 năm 2019. Truy cập ngày 17 tháng 2 năm 2021.
* Logan, Martin; Merritt, Eric; Carlsson, Richard (ngày 28 tháng 5 năm 2010). *Erlang and OTP in Action* (ấn bản 1). Greenwich, CT: Manning Publications. tr. 500. ISBN 978-1-933988-78-8.
* Martin, Brown (ngày 10 tháng 5 năm 2011). "Introduction to programming in Erlang, Part 1: The basics". *developerWorks*. IBM. Truy cập ngày 10 tháng 5 năm 2011.
* Martin, Brown (ngày 17 tháng 5 năm 2011). "Introduction to programming in Erlang, Part 2: Use advanced features and functionality". *developerWorks*. IBM. Truy cập ngày 17 tháng 5 năm 2011.
* Wiger, Ulf (ngày 30 tháng 3 năm 2001). "Four-fold Increase in Productivity and Quality: Industrial-Strength Functional Programming in Telecom-Class Products" (PDF). *FEmSYS 2001 Deployment on distributed architectures*. Ericsson Telecom AB. Bản gốc (PDF) lưu trữ ngày 19 tháng 8 năm 2019. Truy cập ngày 16 tháng 9 năm 2014.

Liên kết ngoài
--------------

|  |  |
| --- | --- |
|  | Wikimedia Commons có thêm hình ảnh và phương tiện truyền tải về ***Erlang***. |

|  |  |
| --- | --- |
|  | Wikibooks có một quyển sách tựa đề 
***Erlang Programming*** |

* Trang web chính thức Sửa đổi này tại Wikidata
* Danh sách các phiên bản
* White paper