Erlang是一種通用的 zhhans 併發；zhhant 平行導向； 函式式 zhhans 程式設計語言；zhhant 程式語言；。Erlang 也可以指 ErlangOTP 的通稱，開源電信平臺（OTP）是 Erlang 的常用執行環境及一系列標準元件。 Erlang 執行環境為專有以下要求的系統設計： 分散式運算 高故障容許度 軟性即時運算 高可用性、不停運作的應用 熱插拔，可以修改程式而不必停機 Erlang 是運作於虛擬機器的 zhhans 解釋型語言；zhhant 直譯式語言；，但是現在也包含有烏普薩拉大學高效能 Erlang 計劃（HiPE）開發的原生程式碼編譯器，自 R11B4 版本開始，Erlang 也支援 zhhans 指令碼方式執行；zhhant 指令碼直譯器；。在程式設計範型上，Erlang 屬於多重典範程式語言，涵蓋函式式、zhhans 並行；zhhant 平行式； 及 zhhans 分散式；zhhant 分散式；。循序執行的 Erlang 是一個及早求值，單次賦值和 zhhans 動態型別；zhhant 動態資料形態； 的函式式程式語言。 它由喬阿姆斯特朗（Joe Armstrong）在瑞典電信裝置製造商愛立信所轄的電腦科學研究室開發，目的是創造一種可以應付大規模並發活動的 zhhans 程式設計語言；zhhant 程式語言； 和執行環境。Erlang 於 1987 年釋出正式版本，最早是愛立信擁有的私有軟體，經過十年的發展，於 1998 年發表開放原始碼版本。 開發及演變歷史 Erlang 得名於丹麥數學家及統計學家 Agner Krarup Erlang，同時 Erlang 還可以表示 Ericsson Language。Erlang 語言由瑞典愛立信電信公司的喬阿姆斯特朗開始設計，開始於公元一九八零年代。最初是以 Prologzhhans 程式設計語言；zhhant 程式語言； 為基礎，幾度改版之後，改成以 Joes Abstract Machine 為基礎的獨立語言執行環境。雖然語言風格仍與 Prolog 相近，不過因 Erlang 語言設計的走向，Erlang 成為具備函式語言特色的 zhhans 程式設計語言；zhhant 程式語言； 見 Coders At Work 一書對 Joe Armstrong 的口述記錄。。 發行版本 1998 年起，Erlang 發布開放原始碼版本，稱為開源電信平臺。開源電信平臺採用修改過的 Mozilla 公共許可證協議發放，同時愛立信仍然提供商業版本的技術支援。目前，Erlang 最大的商業使用者是愛立信，其他知名使用者有北電網路、zhhans 亞馬遜；zhhant 亞瑪遜 以及 TMobile 等 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 scalable AXD301 ATM switch FAQ 中列出的其他使用者包括 Nortel、Deutsche Flugsicherung、TMobile 等。 語言特色 zhhans 並行程式設計；zhhant 平行導向程式設計； 在語言中，可以藉由 spawn 函式，將特定的函式設定為獨立的 zhhans 程序；zhhant 行程；，之後可以做跨 zhhans 程序；zhhant 行程； 通訊。 函式式 zhhans 程式；zhhant 程式； 設計 由於 Erlang 早期以 Prolog 開發製成，受語言特性影響，即成為函式式語言。 單次賦值 每個 zhhans 變數；zhhant 變數 只能跟 zhhans 資料；zhhant 資料； 綁一次，所以，不像一般 zhhans 程式設計語言；zhhant 程式語言； 的 zhhans 變數；zhhant 變數； 可以多次指定為不同的值。單次賦值的好處是狀態單純，使 zhhans 程式；zhhant 程式； 容易閱讀。 及早求值或嚴格求值 Erlang 基本求值策略為電腦語言中及早求值之特性。而且，可以藉由明確使用無引數的 zhhansλ 表示式；zhhantλ 演算式；，將特定函式設定為惰性求值策略。 zhhans 動態資料型別；zhhant 動態資料型態； 與型別系統 有編譯時期的 zhhans 型別；zhhant 型態； 檢查系統 zhhans 支援；zhhant 支援；。 zhhans 快速失敗；zhhant 錯誤先發； 在執行時期發生的錯誤，會由錯誤位置送出訊息，發生錯誤的 zhhans 程序；zhhant 行程； 立刻停止 zhhans 執行；zhhant 動作；。藉由 zhhans 程序通訊機制；zhhant 行程鏈通機制；，可以自動傳遞錯誤、捕捉錯誤，使其他 zhhans 程序；zhhant 行程； 能夠幫助處理錯誤。 zhhans 程式碼；zhhant 程式碼； 熱更新 由於 Erlang 是函式語言，可以撰寫特定的 zhhans 程式結構；zhhant 程式結構；，製作即時更換新版函式的機制。 指令碼語言 Erlang 實作提供了指令碼執行方式。 語言構成 Erlangzhhans 程式；zhhant 程式； 結構以函式定義為主。函式是一組將輸入分別對應到輸出的規則，對應方式遵守數學函式的慣例。此外，Erlang 語言由幾項構句要素所組成，包括文字 或稱原子、數字、列表、值組、字元、字串、二進位資料、模組、與特定用途的關鍵字如 fun end if end case of end spawn receive end 等等。以下段落分別列示並舉例說明 Erlang 程式的基本構成部份，涵蓋資料格式、表示式格式與內建函式。 資料格式 型別 意義與構詞規則 例子 原子 原子是基本資料單元，以一般文字構成。構詞規則有： 以小寫英文字元開頭、不包含空白的連續文字。 以單引號包含的任意連續文字。 hello Hello World true a3b 數字 數字是基本資料單元，可以是整數或實數。 連續數字符號。 包含一個小數點的連續數字符號，並不以小數點開頭也不以小數點結尾。 符合前二項原則，並以 或 符號開頭。 以 分割的數字，前者將表示進位制。 302 31416 1 2 1610 列表 列表是與連結序列相同的資料結構。任一列表大致區分為頭部與尾部，頭部是列表的第一項，尾部是列表除第一項之外的其他部份。 左邊以 、右邊以 符號，包含一串以逗號分隔的零或多項構句要素。 符合前項原則，當存在任一 符號時， 的左邊有一串逗號分隔的構句要素， 的右邊只有一個構句要素。 123 12 值組 值組是將二個、三個或多個資料放在一起的資料結構。 左邊以 、右邊以 符號，包含一串以逗號分隔的零或多項構句要素。 12 字元 Erlang 將字元存為 32 位元的整數。 任何可見的字元，以 開頭、後接該字元符號，即表示字元本身。 任何不可見的字元，可使用以 開頭、後接該字元符號的轉義序列表達。 3 012 x0A n 字串 Erlang 將字串視同一列整數列表。 以雙引號包含任意多個文字，即為字串。 以一列整數列表表達，使其中每個整數專案都落在合理的字元的值範圍，此列也是字串。 Hello World 656667 二進位資料 以左邊 、右邊 符號，包含由位元語法表示的資料。 Hello World 658668678 函式識別項 Erlang 容許用文字表示函式識別項，使程式中可以對指定函式做函式呼叫，或者當做資料傳遞。函式識別項格式為： fun 函式名稱 引數數目 fun a_function3 用途見以下「函式式程式設計」小節。 程式代號 Erlang 容許以內建函式 erlangspawn3、erlangspawn4、erlangspawn1、erlangspawn2 等等，將指定函式啟動為一個程式。程式啟動之後，Erlang 以左邊 、右邊 ，包含一個數字和點號組成的編號，表示此程式代號。 見以下「平行式程式設計」小節。 模組 Erlang 容許將一些程式整理為一個模組。模組的設定，是在原始碼檔案開頭書寫模組標記，格式為： module 模組名稱 export 函式名稱 引數數目，函式名稱 引數數目， import 模組名稱， 函式名稱 引數數目，函式名稱 引數數目， 模組名稱和函式名稱都是原子。 module 模組名稱 定義模組的名字，要與檔名相同。 export 定義模組釋出的函式，模組內的任何函式必須要釋出才能讓外部透過模組呼叫該函式。 import 定義本模組要從其他模組匯入哪些函式，以便本模組自己使用。另外，為了方便程式的撰寫並測試，還容許 compile export_all 定義本模組的所有函式全部對外釋出。 compile export_all 略 巨集 巨集是將一項資料以另一個文字做為代名。 定義巨集的語法是： define 代名，資料 使用巨集的語法是： 代名 Erlang 有一些內定語法，例如模組名稱為 MODULE define hello world test hello 表示式格式 型別 構詞規則 例子 變數 變數是一種提供與資料繫結、賦值的詞彙。Erlang 的變數是單一賦值，一個變數只能賦值一次。 以大寫英文字元開頭的任意連續文字，是具名變數。 以 _ 開頭的任意連續文字，是匿名變數，用於變數必須使用、但相對的值可以忽略的場合。 Number1 _ _nothing 樣式匹配 樣式是指以原子、列表或值組表達的結構，結構中可能包含一些未賦值的變數。 給二個樣式 A 和 B ，樣式匹配是用 A B 表示法，表示要讓 A 對 B 匹配。如果匹配成功， A 包含的未賦值變數都會賦值，並且傳回 B 的值。 A 42 ok Node ok Wikipedia HT 123 函式 函式是由一或多項對應規則組成。每一項規則是將一部份匹配樣式的輸入對映到相對的輸出。 規則：格式為 原子 變數，變數， 表示式，表示式， 在 左邊是函式名稱及搭配的引數列，右邊為函式本體。 函式：格式為 規則；規則； 規則 以分號分隔一或多項規則，並最後以句號結束。 同一函式的每一規則必須以相同的原子開頭，並接受相同數量的 引數列。 函式被呼叫時，會讓呼叫方依序對被呼叫方的每一條函式規則做樣式匹配，比對函式名稱、引數數目、引數樣式等等。首先完成匹配的函式規則會被執行，並且後面的函式規則會被忽略。 見以下「函式式程式設計」小節 函式呼叫 格式為 原子 資料，資料， 表示函式名稱及搭配的引數列。呼叫符合函式名稱及 相同引數數目的函式。 函式呼叫時，所給予的引數可能是已賦值的變數。並且，如果引數是變數，必須是已賦值的變數。 見以下「函式式程式設計」小節 真值比較 比較運算： 相等 不相等 小於或等於 小於 大於或等於 大於 確實相等 確實不相等 真值運算： not 非 and 且 or 或 xor 非此即彼 orelse 或 捷徑求值 andalso 且 捷徑求值 真值比較的結果，如果成功則傳回 true 原子，失敗則傳回 false 原子。 請記得，Erlang 是以 true 和 false 表示布林資料型別。 略 運運算元 Erlang 提供常用的運運算元方便基本運算。運運算元是用在中序的表示式裡，包含 div 商 rem 餘 等。位元算算有 bnot band bor bxor bsl 算術左移 bsr 算術右移 等。用於列表有 列表銜接 列表剔除 等。各種運算式皆可用 調整運算優先順序。 略 防衛式 防衛式是接在 when 關鍵字之後的一組表示式，藉由防衛式的真偽值做程式控制處理。 防衛式的原則如下方所述： 代表 true 或 false 的變數或原子，是防衛式。 任何真值運算式，包括比較算式和邏輯算式，是防衛式。 傳回 true 或 false 的函式呼叫，是防衛式。 以逗號分隔的多個防衛式，是防衛式。 false A 10 erlangis_number N erlangis_atom A 受防衛式限制的函式 函式對應規則格式為： 原子 變數，變數， 表示式，表示式， 若一條函式規則加上防衛式，此規則的處理範圍會多一些限制。受防衛式限制的函式對應規則格式為： 原子 變數，變數， when 防衛式 表示式，表示式， atom_pair A B when is_atom A is_atom B A B 行後註解 任何 符號開頭，往後到行尾的文字皆為註解文字。 HW Hello World λ 演算式 λ 演算式是匿名函式，在 Erlang 以 fun end 關鍵字敘述。格式為： fun 變數，變數， 表示式，表示式， end 使用無引數的 λ 演算式，可以做出惰性求值的效果。 fun XX0 end1 λ x x 0 1 liststakewhile fun X X0 and X10 end 1511 因果式 使用 if end 關鍵字敘述條件判斷原則。格式為： if 防衛式 表示式，表示式， 防衛式 表示式，表示式， 防衛式 表示式，表示式， end parse A if is_number A round A A A 0 natural A is_number A real A is_atom A word A true unknown A end 案例式 使用 case of end 關鍵字，根據一個變數的案例，帶往相對的處理程序。格式為： case 表示式 of 樣式 表示式，表示式， 樣式 表示式，表示式， 樣式 表示式，表示式， end 樣式之後可接 when 防衛式。 show A case A of natural N ioformat Natural number 10B is metn N real R ioformat Real number f is metn R word W ioformat wis metn W unknown U ioformat Unknown structure wn U end 試誤 使用 try catch end 關鍵字敘述試誤的情況與結果。格式為： try 表示式 of 樣式 表示式，表示式， 樣式 表示式，表示式， 樣式 表示式，表示式， catch 樣式 例外 表示式，表示式， 樣式 例外 表示式，表示式， 樣式 例外 表示式，表示式， after 表示式，表示式， end 不需要使用 after 段落時，可省略 after 段落。 樣式之後可接 when 防衛式。 略 接收訊息 每個 Erlang 程式執行時，都可以從自己程式的郵箱中取得由其他程式送到的訊息。可以使用 receive end 關鍵字接收訊息，格式為： receive 樣式 表示式，表示式， 樣式 表示式，表示式， 樣式 表示式，表示式， end 樣式之後可接 when 防衛式。 loop FromPid Result receive FromPid stop Result FromPid Any loop FromPid AnyResult end 傳送訊息 Erlang 容許向程式傳送訊息。使用！關鍵字，格式為： 程式代號！訊息 訊息可以是各種資料格式。訊息資料格式可以是用各種表示式求出的值。 Pid erlangspawn fun receive X X end end 以上產生一個程式。 Pid hello world 以上對 Pid 送出訊息。 列表解析 列表解析，是提供快速建立列表的語法。語法等同於集合建構式。格式為： 變數 表示式中的元素 變數 表示式中的元素 表示式，防衛式 若無防衛條件，列表解析中不寫防衛式。 X X 123 運算結果為 123 內建函式 開源電信平臺包括一個 Erlang 直譯器、一個 Erlang 編譯器、程式節點通訊協定、CORBA、一個分散式資料庫 Mnesia、以及許多程式庫。 內建函式涵蓋了各種方面的功能，涵蓋了系統命令、資料存取、格式轉換、網路通訊、圖形介面、 等。以下列表介紹幾項常用的 Erlang 內建函式。參閱檔案或索引 模組：函式名稱 引數數目 用途 ccd 1 切換到指定目錄位置。 ccd Dcode Dcode ok 當指定目錄不正確時，則保持在原目錄位置。 cc 1 編譯指定的程式碼，之後載入新編譯好的程式。 cc test testerl 必須存在於目錄位置 ok test cc test1 test1erlnone error ioformat 2 按照指定的格式文字將資料印在標準輸出埠。 ioformat 8B c s 2fn 32 a hello 31416 40 a hello 314 ok listssublist 3 由列表中擷取子列表。Erlang 字串是整數列表，於是本函式視同擷取子字串。 listssublist Hello World 2 2 el Hello World 程式 這是輸出 Hello World 的一種方式：譯自官網 httpwwwerlangorgfaqgetting_startedhtml module hello export hello_world0 hello_world iofwrite hello worldn 若要編譯這個程式，將它存為一個名為 helloerl 的文字檔，然後從 Erlang 終端 進行編譯。不要忘了在每個命令的最後加上一個句號。例如： Erlang BEAM emulator version 491 source Eshell V491 abort with G 1 c hello okhello （在 Unix 系統 上，你可以透過在命令列裡輸入 erl 來進入 Erlang 終端。在 Windows 系統 上，你需要開啟一個 命令提示符 視窗，然後輸入 werl 來進入 Erlang 終端，或者在程式功能表中找到 Erlang 的圖示。）從 Erlang 終端 上執行這個程式： 2 hellohello_world hello world ok 函式式程式設計 Erlang 支援函式式程式設計的一般特色，特色包括單次賦值、遞迴定義、λ 演算與高階函式等等。Erlang 函式大致寫法如下，以整數階乘模組為例： module fact export fac1 fac N when N 1 N fac N1 fac 1 1 以下是快速排序演演算法的 Erlang 實作： quicksortqsort List Sort a list of items module quicksort export qsort1 qsort qsort PivotRest qsort X X Rest X Pivot Pivot qsort Y Y Rest Y Pivot 以下是費氏數列求解函式： module example export fibo1 fibo N when N 1 fibo N1 fibo N2 fibo 1 1 fibo 0 0 c example okexample listsmap fun Xexamplefibo X end listsseq 110 11235813213455 函式式程式設計難免以遞迴計算，而消耗了大量遞迴堆疊空間。為了克服這個問題，一般使用累積引數與尾端遞迴等技巧節省遞迴數目：如以下例子。 module test export fibo_accu1 fibo_accu N fibo N 0 1 fibo N C1 C2 when N 2 fibo N1 C2 C1C2 fibo 0 _ _ 0 fibo 1 _ _ 1 fibo _ C1 C2 C1C2 c example oktest listsmap fun Xtestfibo_accu X end listsseq 110 11235813213455 函式式程式設計容許使用高階函式求解。以下例子說明 Erlang 實做複合函式。 f o g ，唸作 f after g 。 AfterF G fun X erlangapply F erlangapply G X end 請注意 after 是 Erlang 關鍵字。因此，以上函式命名為After避開關鍵字。 exampleAfterfun testshow1 fun testparse131416 Real number 3141600 is met ok 平行式程式設計 Erlang 最主要的特色是平行導向程式設計，強調多程式平行運作，並且以訊息對彼此溝通。Erlang 提供了 spawn 函式和！、 receive end 等關鍵字，可以描述在 Erlang 開源電信平臺中的如何啟動一些程式、並且如何讓程式傳遞訊息。此外，平行導向程式設計的精神還強調程式的容錯處理，藉由程式發生錯誤時的訊息傳遞，使其他程式可以得知錯誤的發生，使方便於後續處理。以下分別介紹平行導向程式設計的一般程式撰寫方式，以及錯誤處理的使用方式。 平行導向程式設計 基本的平行程式示範如下： 以下啟動一個程式。 create process and call the function webstart_server Port MaxConnections ServerProcess spawn web start_server Port MaxConnections 以下是在任何程式中，對先前起動的程式送一則訊息 pause 10 。 send the pause 10 message a tuple with an atom pause and a number 10 to ServerProcess asynchronously ServerProcess pause 10 以下是一段接收訊息的程式。每個程式都擁有一份郵箱，可佇留收到的訊息； receive end 程式片斷是從程式的郵箱中取出最早佇留的訊息。 receive messages sent to this process receive a_message do_something data DataContent handle DataContent hello Text ioformat Got hello message s Text goodbye Text ioformat Got goodbye message s Text end 收到 a_message 結果就是 do_something ；收到 data DataContent 結果會呼叫 handle DataContent ； 收到 hello Text 結果教是印出 Got hello message ，收到 goodbye Text 結果是印出 Got goodbye message 。 以下程式，示範產生一組環狀傳遞訊息的程式。 ring_proc Funs Ns listsseq 1 length Funs PPids spawn MODULE listsnth NthFuns Nth Ns Pid ToPid Pid ToPid listszip PPids PidsP func receive ToPid func_msg_ToPid end func_msg_ToPid receive stop ioformat Stop process wn self ToPid stop Message ioformat w transmit message to wn self ToPid ToPid Message func_msg_ToPid end 接收 stop 訊息，就對下一個程式送 stop 訊息；接收到其他任何訊息，就對下一個程式送同樣的訊息。 如果傳送任何其他訊息，就會讓所有的程式不斷對下一個程式傳遞訊息。而以下是測試傳送 stop 訊息的執行結果。 P_ examplering_proc funcfuncfunc 023300234002320 P stop Stop process 02330 stop Stop process 02340 Stop process 02320 容錯處理 Erlang 容錯處理機制，由二個步驟實現：一是將二個程式連線起來，二者之間存在一道通訊管道，可提供錯誤訊息的傳遞 在此使用 link1 函式；二是將程式回報錯誤的機制開啟 在此使用 process_flag2 函式。 使用 link Pid 讓程式連線到另一個程式。 module example compile export_all hello Pid spawn MODULE world link Pid 執行時，以 Pid spawn example hello 啟動程式，此程式將啟動另一個程式，並且與它連線。 但以上程式還不會有錯誤訊息的傳遞機制，因為回報錯誤的開關還沒有開啟。 開啟程式回報錯誤機制。 以上 hello0 函式前段使用 process_flag2 函式，將 trap_exit 標籤開啟，即可開啟程式回報錯誤機制。 hello process_flag trap_exit true Pid spawn MODULE world link Pid 於是，當程式結束時，會送出 EXIT From Reason 資料。程式正常結束時，Reason 為 normal。 另外，spawn 函式另外有程式連線版本，spawn_link 函式，同時啟動並連線到新程式。 分散式程式設計 Erlang 提供分散式機制，能在另一臺電腦啟動一些 Erlang 程式，並由本機電腦對其他電腦的 Erlang 程式傳遞訊息。 當啟動 Erlang 環境時，加上一個網路節點名稱，就進入分散式 Erlang 模式。節點可以使用埠號與其他節點通訊。 erl name node_1 在同一個網域中，網路節點名稱可以使用短名。 erl sname node_1 啟動新的網路節點時，Erlang 使用 epmd Erlang 埠號對應管理系統 指派埠號，提供節點使用。 當知道一個網路節點名稱時，可以在該節點產生新程式。 在指定節點 RemoteNode 啟動一個程式，spawn 啟動引數依序為節點名稱、模組名稱、函式名稱、函式的引數列。 create a remote process and call the function webstart_server Port MaxConnections on machine RemoteNode RemoteProcess spawn RemoteNode web start_server Port MaxConnections 在遠端節點產生新程式之後，可以使用平行式程式設計的技巧，與遠端程式通訊。 Erlang 開源電信平臺提供的程式庫，於分散式程式設計可以使用 net_adm、net_kernel、slave、 等模組，做網路通訊參考分散式 Erlang ， httpwwwerlangorgdocreference_manualdistributedhtml 。 其他程式設計典範 惰性求值 Erlang 程式員可以使用惰性求值。不過，必須使用 λ 演算式，才能做到惰性求值。 以下是惰性求值的一例：假設有個剖析器程式如下，由於及早求值特徵，本程式將不會求解。 expr alt then factor then literal factor then factor then literal factor factor alt then term then literal term then term then literal term term alt number xthen literal thenx expr literal 此處使用 λ 演算式及適當使用函式名稱表示，就能進行求值。示例如下。 expr fun alt then fun factor0 then literal fun factor0 then fun factor0 then literal fun factor0 end factor fun alt then fun term0 then literal fun term0 then fun term0 then literal fun term0 end term fun alt number xthen literal thenx expr literal end 應用 Wings 3D，一個用 Erlang 編寫的三維計算機圖形軟體。 YAWS，以 Erlang 編寫的高效 HTTP 伺服器。 DISCO，以 Erlang 編寫的 MapReduce 架構系統。 Apache CouchDB，以 Erlang 編寫的 MapReduce 檔案式資料庫系統。 RabbitMQ，能搭配 Erlang 運作的訊息佇列系統。 開放電信平臺 WhatsApp：其後端伺服器應用使用了 Erlang 及 FreeBSDErlang 及 FreeBSD。支援了 45 億的活躍使用者 ejabberd 世界上最流行的 XMPP 即時通訊伺服器 EMQX，以 Erlang 編寫的高可用、分散式 MQTT 訊息伺服器。 社群 Erlang Central Erlang Resources 豆瓣小站 Erlang 中文社群 erlangchinaorg Erlang 中文教程 erlangcncom Erlang 中文社群 cnerlangcom Erlang 中文 erlangcnorg 參考資料 延伸閱讀 Early history of Erlang by Bjarne Däcker 外部連結 Erlang 開放原始碼版本 Erlang 愛立信授權版本 因應軟體錯誤建構可靠的分散式系統 Erlang 教學 Category 程式設計語言 Category 併發程式語言 Category 函數語言程式設計語言 Category 宣告式程式語言 Category 模式匹配程式語言 CategoryErlang Category 愛立信 Category1986 年建立的程式語言