Erlang

Erlang [ ɜ ː lŋ ] - Ерланген - функціональна мова програмування з динамічною типізацією, призначений для створення розподілених обчислювальних систем. Розроблено і підтримується компанією Ericsson. Мова включає в себе засоби породження паралельних процесів і їх комунікації за допомогою асинхронних повідомлень і відповідно до моделлю акторів. Програма транслюється в байт-код, виконуваний віртуальною машиною, що забезпечує переносимість. Коротко формулу мови можна виразити як Erlang = функціональна мова + процеси.

Названий на честь датського математика та інженера Агнер Ерланга, засновника наукового напрямку з вивчення мережевого трафіку в телекомунікаційних системах. За іншою версією назва мови спочатку було скороченням від "ericsson language".


1. Синтаксис

Синтаксис успадкований від Prolog; компактний, містить мінімум конструкцій, легкий для освоєння, але не примітивний. Синтаксис підтримує модулі, поліморфні функції, зіставлення зі зразком, анонімні функції, умовні конструкції, структури, обробку винятків, оптимізацію хвостовий рекурсії, що й утворює базовий арсенал сучасних функціональних мов.

Відсутність присвоювання дозволяє Erlang уникнути таких традиційних для імперативних мов проблем в розподілених додатках, як необхідність синхронізації, небезпека виникнення тупиків і гонок.


2. Робота з процесами

Відмінною особливістю мови є модель легковагих процесів (аналогічно потокам в OpenMP), реалізація заохочує створення великої кількості таких процесів. Ці процеси ізольовані один від одного і не мають загального стану, між процесами можна встановити зв'язок і отримати повідомлення про їх стан. Для взаємодії процесів використовується асинхронний обмін повідомленнями. Процес має свою чергу повідомлень, а при її обробці використовується зіставлення зі зразком.

Відсутність необхідності блокування доступу до стану процесу для синхронізації їх взаємодії спрощує розробку. Для роботи з ресурсами, як правило, створюється процес-монітор.

На думку розробників, важливою перевагою мови є принцип роботи процесу "let it crash" ("нехай падає"). Замість перехоплення помилок і спроби продовження роботи, частина програми, що містить ризикований код, виділяється в окремий "процес-смертник", який система завершує в разі виникнення помилки, а процес-батько отримує відповідні повідомлення і обробляє їх. Це дозволяє позбутися від численних перевірок.


3. Розподілене програмування

Запущений екземпляр емулятора Erlang називається вузлом ( англ. node ). Вузол має ім'я і "знає" про існування інших вузлів на даній машині або в мережі. Створення та взаємодія процесів різних вузлів не відрізняється від взаємодії процесів усередині вузла. Для створення процесу на іншому вузлі процесу досить знати його ім'я і, без особливих на те підстав, він може не цікавитися фізичним розташуванням взаємодіючого з ним процесу.

Програми, написані на Erlang, здатні працювати на декількох вузлах. Вузлами можуть бути процесори, багато ядра одного процесора, або цілий кластер машин. Чим складніше додаток і чим більше воно створює процесів, тим легше його масштабувати, і навпаки, якщо не використовуються переваги функціонального програмування, то можна обмежитися єдиним процесом.


4. Приклади

Обчислення факторіала на 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  )  when  N  >  0  ,  is_integer  (  N  )  ->  N  *  fac  (  N  -  1  )  .  % Recursively determine, then return the result  % (Note the period. Meaning 'endif' or 'function end') 

Алгоритм сортування (схожий на швидку сортування):

 %% 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  ]  )  . 

Цей приклад рекурсивно викликає функцію qsort до тих пір, поки елементи не закінчаться. Вираз [Front || Front <- Rest, Front < Pivot] збирає список Front з елементів Rest таких, що елемент Front менше Pivot. Оператор ++ склеює списки.

Можна сортувати складні структури через функцію порівняння:

 % 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 a parameter  qsort  (  Lists  ,  fun  (  A  ,  B  )  ->  A  <  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  ,  S  maller  (  X  ,  Pivot  )  ]  ,  Smaller  )  + +  [  Pivot  ]  + +  qsort  (  [  Y  | |  Y  <-  Rest  ,  not  (  S  maller  (  Y  ,  Pivot  )  )  ]  ,  Smaller  )  . 

Тут вираз

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

схоже на вираз

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

з попереднього прикладу за тим винятком, що використовується функція порівняння Smaller, певна раніше через лямбда-вираз

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


Приклади проектів, що використовують Erlang

  • Yaws (Yet Another Web Server) - веб-сервер, написаний на Erlang.
  • Ejabberd - вільний (GNU GPL), розподілений і стійкий до відмов Jabber-сервер, написаний в основному на Erlang.
  • Nitrogen - каркас для створення веб-додатків на мові Erlang.
  • Chicago Boss - Ruby on Rails -подібний фреймворк з підтримкою Django templating language (DTL) [2], "гарячої" заміною коду, вбудованим SMTP-сервером і розвиненою системою тестування [3]. Повністю використовує можливості OTP.
  • Disco Project - реалізація MapReduce, створена компанією Nokia. Ядро MapReduce написано на мові Erlang, додатки для MapReduce можна писати на мові Python.
  • CouchDB - документо-орієнтована база даних з REST -інтерфейсом.
  • RabbitMQ - Message Oriented Middleware платформа (реалізація AMQP) на Erlang.
  • EADC - ADC сервер на Erlang.
  • Zotonic - CMS, написана на Erlang.
  • Erlyvideo - багатопротокольний відеострімінговий сервер. [4]
  • Riak - розподілена NoSQL база даних, написана за принципами, описаним у статті Amazon dynamo, на Erlang.

Примітки

  1. http://www.erlang.org/news/34 - www.erlang.org/news/34 R15B02 released
  2. Django templates - chicagoboss.org / embedded / chicagoboss / api-view.html (En)
  3. Testing framework - chicagoboss.org / embedded / chicagoboss / api-test.html (En)
  4. Video streaming | Erlyvideo - erlyvideo.ru /