Erlang имеет репутацию своего рода синтаксиса, который так отчаянно требует сахара, что привел к заимствованию добра из Ruby и, в конечном итоге, к изобретению языка Elixir. Однако для тех, кто работает с языками машинного обучения, такими как OCaml или Haskell, это может даже показаться знакомым.

В этой статье я узнаю, о чем этот язык, что вокруг него обсуждают и как он иногда пытается обмануть ничего не подозревающих разработчиков.

Из лаборатории в вашу ладонь

Исследования языка программирования, особенно подходящего для реализации телекоммуникационных решений, начались около 40 лет назад в Лаборатории компьютерных наук Эрикссон. Пролог - язык логического программирования - служил ему прямым предшественником, но позже он оказался слишком медленным для реализации основных функций, а затем эти части были в конечном итоге переписаны на C.В ходе разработки команда сосредоточилась на изобретении минимального языка, подходящего для потребности телекоммуникаций, которые также могут массово работать параллельно с высокой производительностью, предлагая максимальное время безотказной работы. Эти ключевые требования определили особенности языка и связанной с ним экосистемы, а также сделали язык применимым для написания серверов, работающих со скоростью, близкой к реальному времени, с использованием набора библиотек Erlang, называемого Open Telecom Platform (OTP).

Этот результат привлек внимание некоторых компаний, стремящихся внедрить новые решения для обмена мгновенными сообщениями для мобильных устройств. Одной из таких компаний была WhatsApp, и их успех также привлек внимание к Erlang и его платформе.

Что за животное такое Эрланг?

Требования к тому, чтобы сделать Erlang подходящим для реализации телекоммуникационных решений, также определили, какие функции будет иметь этот язык. Erlang - это функциональный язык программирования. Он работает на виртуальной машине, для которой он должен быть скомпилирован, но он также может запускаться с интерпретацией в своем REPL (цикл чтения-оценки-печати) под названием erl. Виртуальная машина Эрланга называется BEAM (Абстрактная машина Эрланга Богдана / Бьорна) и в этом качестве похожа на виртуальную машину Java или .NET. BEAM поставляется с уже упомянутой средой выполнения и библиотекой под названием OTP. Вместе они позволяют писать приложения, которые:

  • распределенный - может работать на нескольких машинах параллельно, но при этом работать как единое целое.
  • отказоустойчивый - изящно обрабатывает ошибки и при необходимости может перезапускать части самого себя.
  • мягкий режим реального времени - время отклика почти такое же низкое, как у программ, используемых для управления кардиостимуляторами или ракетами.
  • высокая доступность - система всегда остается в сети в основном из-за ее отказоустойчивости, а также из-за того, что
  • горячая замена - это означает, что можно перезагружать, заменять или перезапускать части приложения без остановки системы или самого приложения.

В языке реализованы следующие концепции функционального программирования (в определенной степени):

  • функции высшего порядка - функции могут принимать другие функции в качестве аргументов.
  • первоклассные функции - функции можно определять анонимно
  • неизменность - значение переменных не может измениться после первого присваивания.
  • сопоставление с образцом - значения, хранящиеся в составных типах данных, могут быть извлечены в параметрах, охранниках и случаях; он же деструктуризация
  • нетерпеливое вычисление - выражения оцениваются, как только они присваиваются переменной, в отличие от ленивого вычисления, при котором они оценивают только время, в которое они фактически используются.
  • однократное присвоение - переменным нельзя присвоить новые значения после того, как они были инициализированы в первую очередь.
  • понимание списка - создание списков из существующих списков

Он также поддерживает динамическую типизацию, что означает, что тип переменных не принудительно и не гарантируется во время компиляции, а скорее во время выполнения (хотя статическая проверка типа может использоваться с дополнительным инструментом под названием Dialyzer ).

Приложения Erlang обычно выполняются как масса легких процессов, причем процессы Erlang «намного легче, чем поток операционной системы».

Память, выделенная для переменных Erlang во время выполнения, освобождается динамически и автоматически сборщиком мусора, работающим отдельно.

Какой вид животного не является?

По соображениям производительности и другим практическим причинам Erlang пришлось пойти на некоторые жертвы, которые отличают его от других языков программирования FP. Erlang не является чисто функциональным языком, а это означает, что он не свободен от побочных эффектов, фактически, он в значительной степени полагается на них, когда это необходимо по практическим причинам. Он также не является статически типизированным, хотя типы можно проверить во время компиляции с помощью дополнительного инструмента. Среда выполнения Erlang - несмотря на то, что она работает в мягком режиме реального времени - не применима для реализации высокопроизводительных приложений, где на производительность также влияют постоянные факторы, например, при обработке изображений и сигналов и сортировке больших объемов данных, и где низкоуровневый доступ является должен, как написание драйверов операционной системы.

Скажи привет Эрлангу

Здесь мы определяем модуль (контейнер инкапсуляции FP), который экспортирует только одну функцию, которая не имеет ничего общего с делением на ноль, но не принимает аргументов (отсюда и 0), и выводит строку на стандартный вывод. Количество знаков процента может быстро увеличиваться в Erlang, если мы хотим задокументировать наш код (здесь я был зарезервирован, используя только два). Также нельзя отмечать новые строки в строках, как обычно \n, но вместо этого используется ~n, что усугубляет странный синтаксис языка.

Мы можем объявить такое значение в Erlang: Value = 5, но это не будет работать на уровне модуля, только внутри функции. Это сбивает с толку, потому что нам разрешено свободно использовать их в REPL. Однако вполне допустимо определить функцию, которая просто возвращает значение, которое мы присвоили, и позже может быть вызвана в любое время:

days() -> [ mon, tue, wed, thu, fri, sat, sun ].
months() -> [ jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec ].

Эти списки содержат только atom, которые являются автономными значениями, подобными enum, но не беспокоясь об их значении.

Обратите внимание, что в Erlang инструкции заканчиваются точкой, но это не означает, что запятая и точка с запятой останутся без работы.

Дайвинг в

Допустим, мы хотим написать несколько функций календаря, потому что не смогли найти уже реализованные в документации Erlang, или потому что мы недовольны результатами, которые он нам дал (calendar: date_to_gregorian_days / 3 возвращает дни между годом 0 и указанная дата, однако в григорианском календаре нет такого понятия, как год 0).

Мы могли бы сделать что-то вроде этого:

Теперь позвольте мне упомянуть некоторые особенности Erlang, которые мы можем уловить с поличным в этом фрагменте.

  • Строка 1: для немедленного выполнения используйте .
  • Строки 29–33: охранники с when
  • 36: логическое равенство с =:=
  • 37: мы еще не закончили с ; - способом написания альтернативных реализаций на Erlang, здесь else if
  • 39: если бы у меня было else
  • 42, 47: полиморфные функции - на февраль определяем отдельную логику
  • 53: понимание списка генерирует список по дням месяцев
  • 55: сопоставление с образцом для получения начала и конца списка
  • 58: анонимные функции fun
  • 58: логическое неравенство с еще более странным =/=
  • 70–76: перегрузка функции
  • 75: запутать ничего не подозревающих: =<
  • 81: кортежи с фигурными скобками
  • 81,82: делать что-то последовательно с ,

Почетное упоминание, не включенное в код, но может вызвать много головной боли:

Y = 1.
M = jan.
Y =:= 1 and M =:= jan.

это даст вам:

* 1: syntax error before: '=:='

что не очень полезно, но это происходит с сообщениями об ошибках в Erlang. Для тех, кому интересно, проблема не в операторе равенства, а в and, который имеет приоритет, и, следовательно, 1 and M крадет шоу, оставляя интерпретатора в неведении относительно того, что может означать Y =:=. Чтобы исправить это, используйте круглые скобки:

(Y =:= 1) and (M =:= jan).

возвращает true. Космический баланс восстановлен.

Становясь беспомощным

Каким-то образом документация на веб-сайте Erlang точно отражает странность языка и позволяет легко заблудиться. Некоторые функции не там, где сначала могут показаться разумными (hd, tl - начало и конец списков, но не в модуле lists), а некоторые категории (например, erts) просто не имеют смысла для новичков.

Мы можем интерпретировать это как попытку позволить незнакомым разработчикам просмотреть всю документацию, прежде чем предоставить им информацию, которую они ищут. Иногда это может заставить нас чувствовать себя беспомощными вместо того, чтобы получить помощь. Однако сам контент ясен и достаточно прост, чтобы его можно было использовать, поэтому время, потраченное на документацию, не тратится зря.

Вердикт

Кто я такой, чтобы судить о таком мощном и прекрасном языке, как Erlang? Я даже не поцарапал здесь поверхность! Мне следовало поговорить о способах управления параллелизмом в Erlang, библиотеках OTP, его реализации модели акторов и так далее, но, как следует из названия, моей целью здесь было только почувствовать вкус самого языка. Кстати, могу сказать, что Erlang - это очень весело!

Несмотря на свои причуды, его знаменитая производительность и (в остальном) чистый стиль манят узнать больше. В конце концов, он не сильно отличается от других языков FP, особенно от языков ML. Однако он менее строг, и поэтому нырять относительно легко. Также доступны отличные книги для начала работы, и установка набора инструментов также является простым делом.

Я бы сказал, что для тех, кто интересуется передачей сообщений и аналогичными функциями, и не является пуристом, определенно стоит попробовать и поиграть, чтобы познакомиться. Это также будет означать огромную выгоду для тех, кто в противном случае намеревается использовать его дополнительный продукт, Elixir. Erlang может многое предложить и очень хорошо выполняет свою работу в своей области, оправдывая то внимание, которое ему в последнее время уделяется.