Статьи

Эрланг: Привет, мир

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

По этой причине я начинаю новую серию, где я буду регулярно публиковать сообщения об Erlang. Мои статьи будут содержать большое количество кода, и я буду следовать учебникам О’Рейли « Программирование Эрланга Франческо Чезарини и Саймона Томпсона» и « Программирование Эрланга: программное обеспечение для параллельного мира » автора языка Джо Армстронга.

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


    Erlang может быть единственным объектно-ориентированным языком — Джо Армстронг

Но об этом мы поговорим позже — начнем с основ.

Привет мир!

Erlang — это скомпилированный язык, но немедленная настройка сборки только замедлит нас. Мы сможем немного поиграть с языком, используя встроенный интерпретатор escript.

Сначала установите интерпретатор Erlang с помощью:

sudo apt-get install erlang-base

или найдите пакет, который предоставляет escript, если вы используете дистрибутив не Debian или другую ОС.

Это скрипт Hello World:

#!/usr/bin/env escript
main(_) ->
    io:format("Hello, world!\n").

Вы можете запустить его, выполнив:

gedit 01_helloworld.erl   # paste the file contents
chmod +x 01_helloworld.erl
./01_helloworld.erl

Выход будет:

$ ./01_helloworld.erl
Hello, world! 

Как это работает?

Здесь уже много чего происходит: давайте углубимся в то, что мы сделали.

Мы определили одну функцию Erlang, которая по соглашению имеет сигнатуру main / 1, которая вызывается из escript (точно так же, как основная функция в C или Java). Под main / 1 я подразумеваю функцию с именем main, которая принимает один аргумент; поскольку нет определения типа, принудительного для аргументов, перегрузка происходит только с разным количеством аргументов (но сопоставление с образцом означает, что вы не пропустите его). main / 1 и main / 0 или main / 2 — совершенно разные функции.

Функция Erlang, содержащая один случай, состоит из списка действий. В этом случае у нас есть только одно действие:

    io:format("Hello, world!\n")

это вызов функции format / 1 внутри модуля * io *. Если мы посмотрим на документацию этой функции, то увидим:

format(Format) -> ok

Это означает, что Format — это аргумент, который будет выведен на консоль, а ok — это возвращаемое значение. Но почему прописные и строчные различия?

Атомы и переменные

Небольшая сессия в оболочке Erlang прояснит это. Переменные всегда начинаются с заглавной буквы:

$ erl
Erlang R14B04 (erts-5.8.5) [source] [64-bit] [smp:2:2] [rq:2] [async-threads:0] [kernel-poll:false]

Eshell V5.8.5  (abort with ^G)
1> Format = "Hello, world!\n".
"Hello, world!\n"

Erlang REPL печатает нам значение последнего выражения в качестве помощи: на самом деле мы ничего не печатаем явно, определяя переменную.

Хотя строки полезны, у нас также есть целые числа и многие другие типы:

2> SomeInteger = 42.
42

Одним из таких типов является атом , распространенная идиома в функциональных языках. Вы можете думать об этом как об эволюции перечислений, с той разницей, что нет никаких ограничений на атомы, которые вы можете использовать. Атом — это постоянное значение, используемое для сопоставления и сравнения на равенство; он начинается со строчной буквы, чтобы отличить его от переменной.

3> ok.
ok

Поскольку атом — это значение, подобное «Hello» и 42, мы можем присвоить его переменным.

4> AnAtom = ok.
ok
5> AnAtom.
ok

Если мы напечатаем все, атом будет преобразован в строку для нашего удобства.

6> io:format(Format).
Hello, world!
ok
7> io:format(AnAtom).
okok

В последнем случае мы напечатали ok как преобразование атома, а затем оболочка снова напечатала ok как возвращаемое значение io: format / 1. То же самое касается первого звонка.

Наконец, давайте проверим, что мы находимся на реальном функциональном языке. Переменные неизменны:

8> SomeInteger = 23.
** exception error: no match of right hand side value 23

Эта загадочная ошибка означает, что мы пытаемся сопоставить ограниченную переменную (SomeInteger) со значением 23, которое отличается. Таким образом, сравнение не удается; если вы попытаетесь назначить 42 снова, однако:

9> SomeInteger = 42.
42

Значения совпадают, и возвращается 42 (для дальнейшего назначения, например).

Выводы

Код, который мы напишем во время этой серии, будет доступен по адресу:

https://github.com/giorgiosironi/erlang-series

начиная с Hello World сегодня.

Если вы хотите почувствовать Erlang, поэкспериментируйте с оболочкой erl или с интерпретатором escript . В следующий раз мы собираемся решить нашу первую игрушечную проблему с помощью функций Erlang.