О том, как из C# перешел в Elixir/Phoenix +8



Как-то раз пришлось мне менять работу. До этого я работал только с языками типа Python, C++, C# и ещё парочкой подобных. А теперь пришлось начать работать с функциональным языком. Первые впечатления были «да что за фигня?». Однако у меня получилось достаточно быстро адаптироваться. Далее я расскажу об основных моментах, к которым пришлось привыкнуть или которые пришлось понять, чтобы начать писать быстро и адекватно.

1. Pattern matching

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

Пример 1. По определению:

{tuple_item_1, tuple_item_2} = tuple 

– разбивает 2-х элементный кортеж на две переменных, которые далее можно использовать.

[head_item | tail_list] = list 

– разбивает список на первый элемент в списке и список без первого элемента.

Пример 2. Сопоставление в case:

case get_elem(struct) do
  {:ok, elem} -> …
  {:error, reason} -> …
end

Функция get_elem(struct) возвращает кортеж, и case позволяет сразу извлечь данные и выбрать дальнейшую последовательность действий.

Пример3. Сопоставление функций:

def function_1(params, :ok) do
end

def function_1(params, :error) do
end

def function_1(params, _) do
end

Здесь по сути представлена одна и та же функция принимающая два параметра. Сопоставление паттернов позволяет выбрать, какую именно функцию исполнить.

Немного о работе сопоставления паттернов. Сопоставление идет всегда «сверху-вниз». В данном примере при вызове function_1 от двух параметров, сначала произойдет проверка, что второй параметр равен :ok. Если первая проверка провалится, то произойдет проверка на :error. И если опять нет, то мы в любом случае войдем в третий вариант метода. Нижнее подчеркивание обозначает «любые данные», а также то, что пришедшие данные нас не интересуют, то есть мы их не будем использовать. Если бы function_1(params, _) стояла первой в списке, то программа всегда выбирала бы её, и остальные два метода не работали бы никогда. Если не будет найден нужный паттерн, то вылезет исключение.

2. Pipeline

Это конструкции следующего вида:

param_1
|> func_1()
|> func_2(param_2)
…

С первого взгляда кажется фигня какая-то. Но стоит вспомнить о том, что Elixir – функциональный язык. И в функциональном языке вполне нормально делать вычисления функции от функции, без промежуточных переменных. Пайплайн – всего лишь удобная запись. Сам язык просит для ясности начинать пайплайн с переменной или значения.

Пример выше можно переписать следующим образом:

func_2(func_1(param_1), param_2)

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

3. Отсутствие циклов

В Эликсире нет циклов. Этот факт вызвал наибольший шок у меня, и он наиболее сложен для понимания. Далее идет мое мнение и видение, которое может не совпадать с реальностью и теорией.

Корни этого факта в функциональной парадигме программирования, одно из положений которой гласит, что результат работы программы – это работа функции, которая может вызывать другие функции и программа не предполагает хранение промежуточных состояний. Циклы, в свою очередь предназначены, для многократного изменения внешнего по отношению к циклу состояния.

Заменой циклам служат 2 вещи – рекурсия и библиотечные методы работы с enumerable элементами языка.

Немного ещё о мелочах.

1. В Элексире нет классов, но есть контексты. По сути контексты в некотором роде заменяют классы. Наиболее близкое описание контекста глазами си-шарпера: контексты это нечто среднее между классом и пространством имен в шарпе, причем к пространству имен контекст намного ближе.

2. Атомы. В Элексире есть такое понятие как атом. Атом по сути это нечто вроде «метки». Проще всего к ним относится как к особым строкам. В примерах этой статьи уже было два атома: :ok, :error. Благодаря атомам намного проще осуществлять сопоставление паттернов, и сложные логические конструкции. По сути это константы, у которых значением является их имя. Атом всегда имеет «:» перед именем.

3. Как правильно читать заголовки методов. В Elixir принято обозначать методы следующим образом (особенно часто это видно в документации): &function/2. Читается это как метод с именем «function» и арностью 2. Арность – количество принимаемых аргументов.

Что мне помогло влиться в язык.

Во-первых, это справочник на андройде «Elixir Tutorial». Он хорош тем, что кратко охватывает основные моменты языка и его синтаксиса, и его можно почитать в автобусе. Минус: он на английском, так что подойдет не каждому.

Во-вторых, книга «Введение в Elixir» за авторством Сенлорен С., Эйзенберг Д… В данной книге показывают приемы работы с языком и объясняют их. Легко читается и позволяет значительно улучшить свою работу с языком. Также её можно найти на русском языке.

В-третьих, официальная онлайн документация. Она сделана удобно и позволяет быстро находить нужные разделы/методы, с подробным описанием и примерами.

На этом все.

Список приведенных материалов:

1. Elixir Tutorial

2. Сенлорен С., Эйзенберг Д. Введение в Elixir. Введение в функциональное программирование. – O'Reilly, 2017.

3. Официальная документация.

Вы можете помочь и перевести немного средств на развитие сайта

Теги:



Комментарии (13):

  1. ivlis
    /#19605036 / +1

    А чем по вашему Элексир лучше нативного Эрланга? Для меня как раз Эрланг показался абсолютно идеальным языком, а Элексир с какими-то костылями для переходящих с процедурных.

    • Strain
      /#19605276

      Если отбросить незначительные мелочи то Эликсир имеет ровно одно отличие от Эрланга — это лиспоподобные макросы. А в остальном это абсолютно то же самое: абсолютно те же типы и тот же обратно совместимый beam байткод. В своё время пересел с Эрланга на Эликсир именно из-за макросов.

    • zeratul47
      /#19608926

      Я с Erlang не знаком. Ну то есть я знаю, что такой язык есть и на нем Эликсир базируется, но с ним самим я не знаком. Суть такова, что при смене работы мне нужно было начать работать на беком сайта, грубо говоря. Бек начали писать на Elixir/Phoenix. Так что можно сказать это требование компании.

      Единственное что могу сказать — в книге «Введение в Эликсир» была пара примеров на Erlang и мне он показался менее читаемым, чем Эликсир.

  2. eee
    /#19605502

    А F# не рассматривали?

    • zeratul47
      /#19608930

      Как я ответил на коммент выше — я попал в компанию, где уже работали на Elixir/Phoenix. Так что о других функциональных языках я особо не задумывался.

  3. Vladnev
    /#19605962 / +2

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

    • zeratul47
      /#19608936

      Собеседование. Я просто пришел на собеседование, продемонстрировал свои знания, после взял тестовое задание и выполнил его.

      • yudinetz
        /#19611020

        Все это легко обламывается вопросом «А на каких проектах вы уже работали с технологией N? Сколько лет опыта?». Так что вам повезло, или же контора оказалась вменяемая

        • Free_ze
          /#19611628

          Опыт — понятие скользкое, которое само по себе мало, что говорит. Тем более, когда речь идет об экзотических языках и технологиях. HR все равно не проверит, а технические специалисты отсеят проходимцев.

  4. samplex
    /#19608938

    В Элексире нет классов, но есть контексты

    Неверно, в Elixir'e нет контекстов, есть модули. Скорее всего, вы перепутали с Phoenix.Context, но это относится только к фреймворку Phoenix.

    • zeratul47
      /#19608940

      Возможно вы правы. Я все-таки ещё не гуру Эликсира.

  5. Eladan
    /#19608942

    Скажите, пожалуйста, сколько времени занял переход?

    • zeratul47
      /#19608944

      Ну я потратил где-то пару недель просто читая Elixir Tutorial в автобусе, по пути на предыдущую работу (пока увольнялся). Неделю на выполнение тестового задания. И сразу начал работать. Но уверенно писать начал лишь спустя недели 3-4 после начала работы.