Erlang - это чистая информатика

Так говорил мой бывший начальник. Он был одним из тех парней, которые просто понимают, не собираются называть здесь свое имя, так что это не звучит так, как будто я целую задницу, но он определенно был одним из самых умных парней, с которыми я когда-либо работал. И именно он в первую очередь заинтересовал меня Эрлангом.

Кроме того, это не то, как программировать на Erlang, и не сравнение с другими языками, где я пытаюсь сказать, что Erlang лучше, чем язык X. У меня будет несколько примеров кода, но их немного, так как это не цель поста.

Итак, почему?

Я, вероятно, никогда не собираюсь использовать Erlang в своей повседневной работе, так зачем мне тратить свое время на изучение языка, который я никогда не буду использовать. Хотелось бы научиться говорить на латыни сегодня, а есть люди, которые учат латынь. Итак, большой вопрос: могу ли я чему-нибудь научиться у Erlang, что сделало бы меня лучшим программистом? И однозначно ДА.

Давайте поговорим о некоторых основных концепциях Erlang

Неизменяемость (переменные с одним присваиванием)

Одна из первых вещей, которые вы заметите, начав работать с Erlang, - это неизменность переменных. Это означает, что после присвоения значения переменной его нельзя будет изменить. Если вы пришли из мира императивного программирования (Java, PHP, .Net, Python и т. Д.), То научиться жить с этим - большое изменение в мышлении, потому что в наших программах мы все время выполняем присваивания и изменяем переменные. .

Итак, почему это так важно и зачем это нужно? Помните тот раз, когда вам нужно было отслеживать состояние переменной, чтобы попытаться отладить, почему в процессе производства, когда было ровно 14:37 после обслуживания 17-го запроса, переменная станет true вместо false, как должно было быть. был? Вам понравилось тратить время на воспроизведение этой ошибки, чтобы иметь возможность ее отследить? Нет? И я нет.

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

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

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

Функции с несколькими предложениями, сопоставление с образцом и рекурсивность

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

Рекурсивная функция - это просто функция, которая вызывает сама себя.

Возьмем, к примеру, эту функцию, которая приветствует кого-то по-разному в зависимости от пола. На большинстве языков мы бы написали что-то вроде этого (псевдокод):

function greet(Gender, Name)
   if Gender == name then
     print(“Hello, Mr %s”, Name)
   else if Gender == female then
     print(“Hello, Mrs. %s!”, Name)
   else
     print(“Hello, %s!”, Name)

В Erlang это будет выглядеть примерно так:

greet(male, Name) ->
   io:format(“Hello, Mr. ~s!”, [Name]);
greet(female, Name) ->
   io:format(“Hello, Mrs. ~s!”, [Name]);
greet(_, Name) ->
   io:format(“Hello,~s!”, [Name]).

Erlang позволяет нам использовать сопоставление с образцом вместо управляющих структур, таких как IF. Когда шаблон не работает в функции (например, greet (male, Name)), Erlang просто ищет следующую часть функции с другим шаблоном и запускает ее, если она совпадает. Основное отличие здесь в том, что нет необходимости сначала связывать значения, а затем сравнивать их.

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

do_n(F, N) ->
   do_n(F, 0, N, []).
 
do_n(_F, N, N, Acc) ->
   Acc;
do_n(F, Count, N, Acc) ->
   do_n(F, Count+1, N, [F(Count)|Acc]).

Первое определение функции do_n(F, N) - это просто более удобный интерфейс для нашей do_n/4 функции, которая принимает четыре аргумента. Мы передаем анонимную функцию F в do_n и число N, указывающее, сколько раз мы хотим вызвать эту функцию. Затем эта функция вызовет do_n/4, например, так: do_n(F, 0, 10, []), где она сообщает do_n начать счет с 0 и остановиться, когда счетчик достигнет 10.

Во второй части у нас есть рекурсивная функция с двумя заголовками, то есть: два определения функции, которые будут вызываться в зависимости от значения ее аргументов. Каждый раз при вызове функции значение переменной Count будет увеличиваться, и вторая часть функции будет вызываться снова. Теперь мы не видим там ни одного if оператора, проверяющего, становится ли счетчик когда-либо 10.

Первый заголовок функции записывается так: do_n(_F, N, N, Acc), то есть: выполнять это тело функции только в том случае, если 2-й и 3-й аргументы одинаковы. Итак, когда функция вызывается, первым аргументом будет то, что ей передано, а вторым будет 10 в нашем примере, поэтому, если в какой-то момент счетчик не станет 10, тогда это тело функции никогда не будет вызвано.

Эта конструкция может сначала показаться немного странной, но как только вы к ней привыкнете, вы начнете понимать, почему обучение программированию на Erlang так ценно. (Например, если вы видите, что эта функция активно используется в RabbitMQ).

Еще одна интересная вещь заключается в том, что сопоставление с образцом в Erlang сопровождается «деструктуризацией». Это одна из тех вещей, которые сведут вас с ума в следующий раз, когда вам понадобится доступ к глубоко вложенной структуре данных (OMG) на языке, отличном от Erlang. Как только вы научитесь его использовать и привыкнете к его существованию, вы, вероятно, откроете онлайн-петицию, чтобы ваш повседневный язык программирования вскоре получил эту функцию.

Модель Актера

Сама идея наличия миллионов крошечных процессов, составляющих вашу систему, работающих в гармонии для достижения решения, звучит достаточно хорошей причиной, чтобы уже начать изучать Erlang. Интересно, почему такая отрасль, как Telecom, которая в принципе не может потерпеть неудачу, все еще активно использует Erlang. Этот способ вычисления называется моделью актера, он был введен Карлом Хьюиттом в его знаменитой статье: Универсальный модульный формализм ACTOR для искусственного интеллекта.

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

И последнее, но не менее важное: СИНТАКСИС.

Когда-то я был разработчиком для iOS, но раньше, еще в 2008/2009 году, у нас был только Objective-C, и все еще приходилось беспокоиться о распределении памяти. И я помню, что у меня тогда был начальник, который говорил, что синтаксис Objective-C может быть клингонским. На самом деле это не имело ничего общего с Erlang, я просто хотел рассказать эту историю, чтобы показать, что мы действительно можем привыкнуть ко всему.

Есть много жалоб на синтаксис Erlang. Ну, люди даже создали Эликсир поверх него, чтобы он выглядел лучше (я знаю, я слишком упрощаю Эликсир). И да, если вы пришли из семейства языков ALGOL, тогда, конечно, вы почувствуете себя немного иначе, я даю вам это, но если вы хотите узнать что-то новое, я думаю, что синтаксис Erlang поможет вам напомнить вам: «Эй ! Я не думаю, что есть только один способ делать что-то », - все время. Для языка, который имеет совершенно новую парадигму, такую ​​как модель акторов и параллельное программирование, я думаю, что совершенно другой синтаксис - это просто вишенка на торте, вам не кажется?

Книги и справочники

Я изучил Erlang, прочитав эту книгу: Выучите Erlang на благо!

Еще один хороший вариант: Программирование на Erlang: программное обеспечение для параллельного мира.

Также неплохо было бы прочитать некоторые официальные документы, и я тоже немножко это сделал: http://erlang.org/doc/design_principles/des_princ.html

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

Чтобы попрактиковаться, я начал разбираться с проблемами Project Euler с Erlang, и вот некоторые из них. Мой Erlang Project Euler Challenge.

Вывод

Итак, почему я выучил Эрланг? Или зачем тебе? Потому что, по моему скромному мнению, это даст вам больше информации обо всех местах, где ваш код изменяет состояние, что на самом деле в этом не было необходимости. Имейте в виду, что чем больше вы напишете чистых функций, функций, которые всегда возвращают одно и то же значение для одних и тех же аргументов, тем легче станет доказать правильность этого кода, например, написав для него модульные тесты. В Erlang есть понятие сопоставления с образцом. Это буквально изменит то, как вы видите код, и заставит вас задуматься, почему выбранный вами язык не поддерживает эту функцию. Почему так много «если»? !!!! Модель акторов даст вам новый взгляд на слова инкапсуляция и, вероятно, заставит вас подумать, что ООП, которое мы делали до сих пор, просто помещает пространства имен вокруг коллекций связанные функции. Наконец, синтаксис покажет вам, что все не так плохо, как кажется сначала, и станет легче, кроме того, он покажет вам, что на самом деле вещи должны быть такими, как они выглядят.

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

Понравился пост? КАК НАСЧЕТ ХЛАПКА?