В этом году я провел некоторое время с 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.