Основы Erlang: синтаксис и пунктуация

(Из ленты )

Мои теоретичесие рассуждения о месте Erlang в современном мире
Интернете
 Вы
можете почитать в отдельной статье. Если сомневаетесь интересно Вам это
все или нет — то прочтите сначала её. Сегодня я постараюсь вернуться с
небес на землю и пройтись по азам этого пугающего многих языка
программирования. Коротко и по делу.

Установка ничем особым не выделяется, дистрибутив рекомендую брать
отсюда,
если до сих пор пользуетесь отсутствующей в списке ОС — лучше сначала
исправить этот факт.

После установки в $PATH окажутся исполняемые файлы:

  • erl — одновременно интерактивная консоль и запуск приложений;
  • erlc — компилятор в байт-код для виртуальной машины BEAM или
    нативный код посредством HiPE, напрямую использовать не придется
    практически.

Со всем что будет обсуждаться в этой статье можно эксперементировать
просто в интерактивной консоли, которая запускается просто командой
erl без аргументов.

Пунктуация

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

  • Все функции заканчиваются точкой
  • После каждого выражения в функции — запятая;
  • Все ветви кода (case, if, ...), кроме последней, заканчиваются
    точкой с запятой
  • После заголовка функции и условий ветвления пишется стрелка ->

Маленькая демонстрация:

foo(X, Y) ->
  Z = X * X,
  if
    Y > 0 ->
      Z + Y;
    true ->
      Z - Y
  end.

К слову, функции возвращают результат выполнения последнего выражения, в
данном случае оно представляет собой весь блок if, а end
обозначает его окончание (не функции).

Синтаксис

  • Foo — все что начинается с английской заглавной буквы —
    переменная, специально объявлять ничего не нужно
  • _ — сам знак нижнего подчеркивания и все что с него
    начинается — особый случай переменной, значение которой не значимо
    для программы и при первой возможности «выкидывается»
  • Цифры в основном как обычно, есть научная нотация в духе 1.23e4
    (1.23 умножить на 10 в степени 4) и системы исчисления с другим
    основанием, скажем двоичная — 2#101010
  • foo — с строчной буквы начинаются атомы, по сути константы,
    используются повсеместно:

    • названия функций и модулей
    • true и false — булевые значения
    • ok — типичный результат успешный результат выполнения
  • ?FOO — хоть официально и называются константами, но по сути —
    макросы, перед компиляцией заменяются на заранее определенный кусок
    кода 
  • {foo, bar} — кортеж, набор данных фиксированной длины
  • [foo, bar] — простой однонаправленный список произвольной длины
  • "foo" — текстовая строка, представленная в виде
    однонаправленного списка (что не эффективно с точки зрения
    потребления памяти, до 4 байт на символ)
  • <<"foo">> — бинарная строка, может содержать что угодно,
    в.т.ч. и текст; все что не цифры по возможности лучше хранить в этом
    типе данных.

Сопоставление (pattern matching)

Очень мощная концепция сопоставления используется в Erlang на
каждом углу. В базовом варианте работает примерно так:

{ok, Result} = foo().

Если в функции foo все прошло нормально, то она возвращает, например
{ok, 123}, и переменной Result окажется лишь значение 123.

Если же возникла какая-то проблема, то она вернет что-то другое, скажем
{error, timeout}, приложение столкнется с несоответствием левой и
правой части (атомы ok и error разные) и прекращает свое
выполнение (если бы было чего выполнять).

Базовый принцип, надеюсь, понятен. Подобным образом выбирается какую из
реализаций функции использовать, в какую ветвь case идти и т.п. В
общем есть много других более сложных применений, но о них в другой раз.

Списки

Со списками есть три особые операции:

  • [Head | Tail ] = [1, 2, 3, 4] — вытащить элемент с головы
    списка, работает по принципу сопоставления, в Head окажется
    1, а в Tail[2, 3, 4]
  • [1, 2] ++ [3, 4] — конкатенация, результатом будет [1, 2, 3, 4]
  • [N * N || N <- [1, 2, 3], N > 1] — выглядит замороченно, по
    сути это обычный отображение (map) с фильтрацией (filter) — то
    есть выражение перед || применяется к каждому элементу списка,
    значение которых попадает в переменную N, а после запятой —
    условие, накладываемое на N; таким образом результат будет [4,
    9]

Бинарные строки

C ними намного больше всяких трюков и преобразований, приведу наиболее
значимые:

  • Binary = <<Integer:64>> — преобразовать целое число Integer
    в бинарную строку Binary длиной 64 бита (для примера, может быть
    любой
  • <<Integer1:32, Integer2:32>> = Binary — распокавать обратно
    бинарную строку в целые числа, но уже два по 32 бита; чем-то похоже
    на операцию [H | T] у списков, но намного более гибко
  • Binary3 = <<Binary1/binary, Binary2/binary>> — конкатенация
    бинарных строк, результат окажется в Binary3
  • << <<(N * N)/integer>> || <<N>> <= <<1, 2, 3>>, N > 1 >> — аналог последнего примера для списков, только для
    бинарных данных; результат аналогичен — <<4, 9>>; к слову
    официально это называется binary comprehensions, а для списков —
    list comprehensions

Заключение

Очень многое пришлось опустить, иначе самое главное затерялось бы, да и
объем статьи сильно вырос. Подробности всегда можно найти на
официальном сайте, в man’ах, да и просто
погуглив. 

Удачного освоения Erlang!

Источник: Основы Erlang: синтаксис и пунктуация