elixir developer что это

Создание Elixir-приложения на примере. От инициализации до публикации

Данная статья участвует в конкурсе от Wunsh.ru — русскоязычное сообщество Elixir. Практики и просто сочувствующие — присоединяйтесь!

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

Вступление

«Elixir — динамический, функциональный язык программирования, разработанный для создания масштабируемых и легко поддерживаемых систем.» — elixir-lang.org

Инициализация нового приложения

Шаблон своего будущего mix-приложения проще всего создать с использованием команды ‘mix new app_name’.

Данная команда создаст своего рода скелет вашего приложение. А именно папку с названием quadratic_equation и следующей структурой файлов и папок:

Есть несколько соглашений об именах и содержании файлов, знание которых вам пригодятся:

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

Тестирование приложения

Сборка и запуск приложения в iex

iex — это интерактивная консоль для работы с приложениями поставляемая вместе с Elixir. Относительно Ruby это аналог irb.

Написание кода приложения

В силу простоты приложения, весь код мы будем размещать в теле модуля верхнего уровня, а именно в QuadraticEquation.

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

Пожалуй начнём с написания тестов. Как раз определимся с вариантами ответов нашего публичного метода. Тесты мы будем размещать в специальном файле сгенерированным для модуля верхнего уровня.

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

Не будем запускать тесты прямо сейчас, для начала определим функцию calculation в QuadraticEquation. Данная функция будет принимать три числовых значения, а именно переменные a, b и с присущие квадратному уравнению в традиционной форме записи.

Теперь запустим тесты и удостоверимся, что они не прошли.

Добавим решение квадратного уравнения в нашу функцию. А также укажем ожидаемые нашими тестами возвращаемые значения функции.

Не буду приводить приватные методы в статье, они есть в исходном коде примера на GitHub.com.

Примечание. Аннотации @moduledoc и @doc необходимы для развёрнутого описания сути модуля и для описания сути функции. Также exdoc умеет генерировать из них пролинкованную документацию, а hex.pm сгенерирует и выложит доки сам. Для того, чтобы скрыть модуль / публичную функцию в сгенерированной документации используется директива @moduledoc false и/или @doc false.

Создание mix задачи

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

В mix-приложениях все задачи принято располагать в отведённой для этого папке lib/mix/tasks. Так что первым делом добавьте эту папку себе в приложение.

Затем создайте в данной папке для задач файл с именем содержащим имя основного модуля приложения и название задачи.

Задача будет не сложной, в её обязанности входит вызов функции calculation модуля QuadraticEquation.

Публикация приложения в Hex

Hex — библиотека Erlang и Elixir приложений.

Вам потребуется указать username, email и пароль. А также подтвердить введённый вами email пройдя по ссылке из отправленного вам письма.

Вы также можете добавить в документацию README файл, для этого включите его в конфигурацию приложения.

Заключение

Как вы можете видеть генерация скелета приложения с помощью Mix дело не хитрое, так же как и его публикация в менеджер пакетов. Писать свои приложения на Elixir не так уж и сложно. Изучайте язык, находите идеи и реализуйте их. Вперёд!

Литература

Если вам интересен функциональный язык программирования Elixir или вы просто сочувствующий то советую вам присоединиться к Telegram-чату Wunsh && Elixir.

Источник

Почему я ставлю на Elixir

6 лет я создавал приложения на языке Ruby и фреймворке Rails. Я щупал всякие новые языки программирования по мере их выхода, но Elixir – первый из них, который меня действительно увлёк.

В своё время Ruby уделал всех

Язык Ruby и фреймворк Rails полностью поменяли способ создания веб-приложений. Они дали начало религии ценностей для сообщества программистов. Они первые предложили идею, согласно которой инструменты программиста должны быть оптимизированы для продуктивной и радостной разработки.

Именно они постулировали, что задача тестирования и доведения кода до работоспособного состояния лежит на разработчиках. Другие языки и фреймворки насмехались над таким подходом, пока он не начал завоёвывать популярность. После этого они стали включать принципы, присущие сообществу Ruby, в другие языки и фреймворки.

Ruby прошёл путь от скромного положения невразумительного языка до одного из самых популярных языков, в основном из-за фреймворка Rails и огромного лидерского потенциала таких людей, как DHH, Wycats, Aaron Patterson, Jose Valim и множества других. Но периодически, и тут и там начинают вылезать артефакты, оставшиеся из-за такого скромного старта языка.

Убегающая память

Зед Шо [Zed Shaw] в посте «Rails – это гетто» разглагольствует на тему проблем со сборкой мусора, из-за которых первые приложения на Rails перезапускались каждые 4 минуты.

Один из самых популярных серверов для Rails сегодня – это unicorn. Моё веб-приложение – это приложение для Rails, оно довольно простое, по сравнению с другими приложениями, которые я разрабатывал. Я перенёс его на сервер с 512 Мб памяти, и после нескольких дней работы мой unicorn съел всю доступную память и приложение начало тормозить.

Решение? unicorn-worker-killer. Не слишком отличается от более ранних решений.

Мой сервер способен обслужить два потока unicorn, забирающих большинство ресурсов, базу данных Postgres и несколько других приложений. Отзывается он, правда, довольно быстро, поэтому работу свою делает.

Параллелизм

Хотя я занимаюсь разработкой приложений для Rails уже несколько лет, я ни разу не использовал дополнительные потоки в приложениях для продакшена. Сам по себе Rails нормально работает с потоками, но по моим ощущениям, от них возникают одни лишь проблемы – я пробовал использовать их в Java, C++ и других ООП-языках.

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

Тестирование – главная парадигма сообщества Ruby, поэтому неудивительно, что большинство рубистов не трогают многопоточность, поскольку её практически невозможно тестировать, а её баги очень сложно воспроизводить.

Как и большинство нормальных разработчиков, я использую sidekiq или resque для обработки вещей в параллели. В Rails 2.2 добавили безопасность для потоков, но в Rails 4.2 добавили Active Job API, которое оказалось гораздо более полезным.

Но процессы, выполняемые в фоне, нужно выполнять в фоне. А критичные вещи нужно выполнять в главном процессе – чтобы можно было среагировать на ошибку или проследить, что все транзакции были успешно завершены, перед тем, как завершать задачу.

Читайте также:  какой максимальный срок декретного отпуска

Скорость

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

Какое-то время выполнение функциональных и юнит-тестов у проекта, над которым я работал, занимало порядка 20 минут. Я использовал hydra для распределённых тестов, но мне всегда было сложно сделать так, чтобы тесты проходили (скорее всего, из-за слишком сложного и не особо красивого кода).

Даже запуск тестов занимал секунд 40. Вы когда-нибудь ждали 40 секунд, только чтобы увидеть: “syntax error, unexpected end-of-input, expecting keyword_end”, или ещё такую же ерунду? А я ждал.

Что делать? Zeus. Прекрасный gem, которая предварительно загружает всё необходимое для приложения и может загрузить (согласно описанию на github) любое приложение для Rails за секунду. Он мне нравится, и я рекомендую его всем.

Но как они достигли такого быстродействия? Просто написали его на Go.

Scala

Пару лет назад я обрадовался появлению Scala. Потом я начал её использовать – и ненавидеть.

У неё есть много концепций из функционального программирования. Фреймворк akka позволяет писать надёжные приложения. Она запускается в JVM, поэтому может использовать любую библиотеку из Java, а JVM очень хорошо обработана на предмет быстродействия.

Сам язык приятный. Но что меня остановило? JVM. Управление пакетами jar слишком сложное, если сравнить его с Rubygems и Bundler.

Есть, конечно, всякие решения: SBT, Maven, Ivy,- но все они заставляют меня морщиться, когда мне нужно импортнуть чью-либо чужую библиотеку. Может, Ruby меня испортил, но управление пакетами в нём – одна из основных причин моей продуктивности.

Что меня ещё напрягало в Scala, так это что используемые мною библиотеки были написаны на Java людьми, чьи ценности и установки сильно отличались от моих.

Создание веб-приложения на Scala в фреймворке Play! выглядело так же, как создание веб-приложения на Java в фреймворке Play!, кроме чуть более простого синтаксиса и возможности поиска шаблонов. Хотя Rails сильно повлиял на Play!, разница между ними чувствуется интуитивно.

Экосистема Elixir

Управление пакетами через Mix

Впервые погрузившись в Elixir, я наткнулся на Mix. Это гибрид Bundler и Rake в Ruby. Что мне в нём так нравится – это то, что он не хуже, чем Bundler и Rake. Он и не сильно лучше, но планка поднята достаточно высоко и подняться до неё – это уже достижение.

Mix делает свою работу прекрасно, не мешается под ногами, и не заставляет вас возиться с XML.

Виртуальная машина Erlang

Elixir работает в виртуальной машине Erlang, и поддерживает почти все ценности сообщества Erlang. Elixir и Erlang гордятся фокусировкой на функциональном программировании, которое устойчиво к ошибкам и хорошо масштабируется.

Веб-фреймворк Phoenix

На phoenix framework, очевидно, сильно повлиял Ruby on Rails, и создание веб-приложения для Phoenix выглядит очень похоже на создание приложения для Rails. Мне нравится роутер у Rails. А также ActionController, ActiveRecord, Rails Views и способ, каким вы можете программировать приложение. Мне нравится организация приложений в Rails.

Phoenix так похож на Rails, что вам покажется, будто вы делаете приложение для Rails, кроме того, что оно будет работать под Elixir и иметь все преимущества Elixir и виртуальной машины Erlang.

Кроме этого, он поддерживает WebSockets через каналы. Это позволяет вам легко использовать WebSockets, предоставляемые в Firebase.

Лидерство

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

Движение Rails приобрело такой большой импульс, благодаря работе DHH, Aaron Patterson, Jose Valim, Wycats и кучи других. Не было такого, чтобы запустили первую версию Rails и работа встала.

Это всё старая привычка много работать – а построение грамотного сообщества требует большой работы. Jose Valim, Chris McCord, и все остальные члены основных команд Elixir-Lang и Phoenix работали и продолжают работать над процветанием их сообщества.

Веб ждут великие преобразования

Признайте – CRUD-приложения на сегодняшний день являются товаром. Следующий стартап «AirBnB для аренды кетчупа» скорее всего не выживет.

Победят те, кто примут изменения в технологиях. То, что в WebSockets, процессы и параллелизм в Phoenix и Elixir легко достижимы, и из-за них не надо поступаться лёгкостью программирования, просто меняет всё дело.

Я очень люблю Ruby on Rails. Он поменял способ создания веб-приложений в годах 2005–2014. Думаю, что Elixir и Phoenix произведут такой же эффект в годах 2015–2025.

Если вы уже хотите начать делать веб-приложения на Phoenix и Elixir, вот вам мой тьюториал.

Источник

«Введение в Elixir» — первая книга по Эликсиру на русском

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

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

«Введение в Elixir» — стандартный представитель литературы по языкам программирования. Рассказ ведётся последовательно, от основ синтаксиса к продвинутым модулям и техникам. Примеры синтетические, но при этом иллюстрируют текст так, что сразу становится понятно о чём идёт речь. Учитывая, что язык — выразительный, а набор инструментов, доставшийся в наследство от Эрланга впечатляет, скучать не приходится.

Далее рассмотрю каждую из глав подробнее.

Глава 1. Устраиваемся поудобнее

Здесь всё стандартно. Подготовка к работе с языком, объяснение основы основ и коротенький мастер-класс по работе с интерактивной оболочкой.

Глава 2. Функции и модули

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

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

превращается в элегантного вида

Или как вам такая особенность? Добавляя комментарии к функциям можно тут же получать полноценную документацию, встроенными в язык средствами.

Глава 3. Атомы, кортежи и сопоставление с образцом

Опыт работы с книгой зависит от того, с какими языками вы уже знакомы. Если ранее вы не сталкивались с функциональными языками или не знакомы с синтаксисом Руби, то уже здесь начнутся откровения.

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

Читайте также:  что делать если кошка перестала мяукать

Но такая простая идея существенным образом (при использовании других механизмов языка) оказывают влияние на стиль программирования на Эликсире.

Например, здесь не переопределяется одна и та же функция трижды. На самом деле это 3 разные функции, каждая из которых может быть выбрана через сопоставлении с образцом первого аргумента-атома.

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

Глава 4. Логика и рекурсия

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

Глава 5. Взаимодействие с человеком

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

Глава 6. Списки

Надеюсь, что мне удаётся пробудить в вас интерес к языку. Помимо интересных синтаксических особенностей и классных идей в основе, всё работает потрясающе быстро. Неспроста, Эликсир сравнивают по скорости работы с Го и Растом, а по скорости разработки с Руби.

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

Вот такое вот функциональное программирование с человеческим лицом.

Глава 7. Пары имя/значение

Меня порой спрашивают. Раз в Эликсире нет объектов, то как же нам работать со структурированными данными? Кортежи и списки — это хорошо, но они не позволяют достать значение по имени. Эликсир, хоть и молодой, но уже зрелый (даже продакшн реди) язык. Поэтому разработчики предусмотрели механизмы для решения этой задачи. В Эликсире есть типы данных, в которых можно получать значение по ключу. И в этой главе рассматривается именно они — от словаря до структуры.

Глава 8. Функции высшего порядка и генераторы списков

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

Не самая интересная глава, но узнать об этих возможностях будет не лишним.

Глава 9. Процессы

Если у вас неплохой опыт программирования, то до текущего момента вам могло быть скучновато. Спешу вас обрадовать, самое интересное о киллер-фичах Эликсира начинается прямо сейчас!

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

На самом деле, процессы — это ещё одна организационная единица программы, наравне с функциями и модулями, которая является независимым компонентом, способным принимать и отправлять сообщения. Работающая программа — это набор процессов.

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

Глава 10. Исключения, ошибки и отладка

С отладкой в Эликсире пока не всё гладко, так как не существует полноценных нативных инструментов. Самое популярное — Pry (который пришёл из Руби) и :dbg (из Эрланга). На самом деле, ими вполне комфортно пользоваться, и в книге даётся неплохой разбор второго из них.

Глава 11. Статический анализ, спецификации типов и тестирование

В программировании известны три основных класса ошибок: синтаксические ошибки, ошибки времени выполнения и семантические ошибки. Компилятор Эликсира обнаруживает и сообщает о синтаксических ошибках. Остаются логические ошибки, когда вы требуете от Эликсира одно, имея в виду другое. Журналирование и трассировка могут помочь в поиске подобных ошибок, но всё же лучше постараться предотвратить их появление с самого начала. И в этом вам помогут статический анализ, спецификации типов и модульное тестирование. Обо всём этом рассказывается в этой главе.

Эликсир имеет очень нетривиальные возможности в этих областях. Например, встроенные в документацию тесты:

Теперь, можно быть уверенными, что документация всегда будет актуальной!

Глава 12. Хранение структурированных данных

Как бы нам ни хотелось иметь чистые функции, на практике это невозможно, ведь данные нужно где-то хранить. Для этого у Эрланга есть куча встроенных инструментов, которыми к счастью можно пользоваться и из Эликсира. В этой главе рассматриваются ETS и Mnesia.

Просто представьте, что вам больше не понадобится Редис, в качестве внешней зависимости. Ведь его «заменитель» встроен прямо в язык и поддерживается из коробки.

Глава 13. Основы OTP

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

Оказывается, OTP — это фреймворк для написания распаралелленных и высоконадёжных приложений. Он использует все фишки виртуальной машины Эрланга и позволяет программистам задумываться только о бизнес-логике, а не о деталях реализации.

Самыми популярными модулями являются Supervisor и GenServer. Выглядят они так:

Узнать о них подробнее можно тут и тут. Либо в текущей главе книги.

А ещё Эликсир предлагает штуку, о которой мечтают все эрлангисты — утилиту Mix.
Её обзор тоже есть в книге.

Глава 14. Расширение языка Elixir с помощью макросов

Глава 15. Phoenix

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

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

Выводы

Книга исключительно годная. Я уже несколько месяцев занимаюсь проектом Вунш, где мы знакомим русскоязычных читателей с прекрасным Эликсиром. И мне всё равно было интересно читать книгу, удалось почерпнуть нюансы при работе со знакомыми частями языка и узнать о других возможностях, с которыми не приходилось раньше сталкиваться.

Надеюсь, мой обзор вам пригодится. Всем хорошего дня и побольше полезных книг!

Источник

Elixir

Здравствуйте, сегодня я Вам расскажу о современном языке программирования под BeamVM (или ErlangVM).
Первая часть является неполным введением в основы, а вторая часть статьи показывает на простых примерах главные особенности языка, новые для erlang-разработчика.

Читайте также:  ip20 или ip65 чем отличается светодиодная лента

Два года назад вышла 0.1 версия elixir, которая и была представлена хабрасообществу раньше.

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

На данный момент, elixir стал самым популярным языком программирования (естественно, помимо erlang-а), построенным поверх BeamVM. Вплоть до того, что автор erlang Joe Armstrong посвятил статью, а Dave Thomas написал книгу. За два года очень многое изменилось, язык сильно стабилизировался и обрёл более или менее конечный вариант для версии 1.0. За это время, из elixir исчезла объектная модель, остался Ruby-подобный синтаксис, но добавился метапрограмминг и полиморфизм, которые органично, в отличие от объектно-ориентированной парадигмы вписываются в Beam VM.

Чтобы опробовать у себя, можно скачать его с гитхаба:

В elixir-е имеется интерактивная консоль iex, в которой можно сразу же всё и попробовать. В отличие от erlang-а в консоли elixir-а можно создавать модули, как будет показано ниже.

Далее, “# =>” показывают значение выражения:

Типы данных в elixir-е такие же, как и в erlang-е:

Строки в elixir-е, как и в erlang-e могут быть представлены через списки или через binary:

В отличие от erlang, elixir использует везде binary, как стандартную имплементацию строк из-за скорости и компактности их перед списками букв.

A так же есть многострочные строки:

Вызов функций, мы уже видели выше для модуля, но можно и так, опуская скобки:

Хороший стиль программирования для elixir-а рекомендует, если и опускать скобки, то при использовании макро.
Coding Style в стандартной библиотеке говорит о том, что для вызова функций скобки должны быть.

Переменные в elixir являются по-прежнему immutable, но можно делать reassigment:

Изменять переменные можно только между выражениями, а внутри одного выражения это будет по-прежнему match. При этом сохранился весь pattern matching из erlang и при этом можно с помощью ^ делать их неизменяемыми как в erlang-е:

После того, как я сам начал программировать на elixir-е, смотреть на код erlang, который создаётся часто через copy-paste с изменением одного значения(а такая необходимость есть почти в каждом проекте, который я встречал) или постоянные повторения определённого паттерна, которые увеличивают код, мне так и хочется переписать их грамотно на elixir-е.

А сейчас хотелось бы показать на простых примерах нововведения для erlang-разработчика, a именно метапрограммирование, полиморфизм, а также синтаксический сахар, которые сильно упрощают код.

Начнём с метапрограммирования. В elixir-е всё является выражениями, по крайней мере насколько это возможно(«Everything is an expression»).
Первый пример, мы возмём самый обычный модуль с одной функцией, как наш эксперимент.

Запищем его в фаил и скомпилируем его так:

Либо копируем в консоль, и наш модуль компилируется там. В любом случае, внимательно смотрим, что происходит вовремя компиляции. На данный момент ничего особенного.

Давайте изменим наш пример немного:

Теперь, вовремя компиляции мы можем увидеть «Hello compiler».

Теперь попробуем изменить что-то в нашем модуле, в зависимости от компиляции:

Теперь, мы если мы скомпилируем код, то в зависимости от того, как мы его компилируем, мы можем увидеть:

Либо, если мы скомпилируем наш модуль так, то получим другое действие нашей функции:

А теперь, попробуем сделать что-то более интересное, например сгенерировать код.
В erlang-коде часто можно встретить такой или подобный код:

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

В elixir-е, мы можем получить ту же скорость работы функции, не повторяясь, если будем генерировать те же самые функции во время компиляции:

lc inlist do — это list compression в языке elixir, пример использования:

Сейчас с помощью list compression мы сгенерировали по две функции(или точнее match для функции).

Макро в elixir-e действуют, как в clojure(программисты lisp-а будут чувствовать себя, как дома), у любого кода можно увидеть его AST:

Как видно из примеров, AST состоит из кортежей с тремя элементами:
Теперь, попробуем написать наше первое макро:

Теперь используем наше макро:

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

А теперь, используя наши знания выше, мы можем вынести компиляцию регулярного выражения, тем самым сделая наш runtime код быстрее:

В данном примере, мы вынесли компиляцию регулярного выражения вне функции. Используя Macro.escape (есть много других полезных функций в модуле Macro) мы вставили в нашу функцию уже скомпилированное регулярное выражение, имея по-прежнему в коде читабельный вариант. Собственно, в эликсире с регулярными выражениями не нужно этого делать, так как %r макро это уже делает за вас, в зависимости от того, если можно сразу скомпилировать регулярное выражение.

Таким образом, мы можем сравнить скорость нашей функции:

Пример показывает, что мы можем использовать библиотеку Enum над любым типом данных, который имплементирует протокол Enumerable.

Имплементация для протоколоа может находиться где угодно, независимо от самого протокола: главное, чтобы скомпилированный код находился там, где BeamVM может его найти(т.е. в :source.get_path). Т.е. например, Вы можете расширять существующие библиотеки, не изменяя их код для своих типов данных.

Ещё один интересный встроенный протокол — это access protocol — возьмём на примере верхнего списка символ-значение:

Мы сделаем очень простой пример с бинарным деревом, который будет находиться в записи(record) Tree и для нашего дерева мы тоже имплементируем Access протокол.

Теперь точно так же мы можем находить наши значения через Access Protocol

Протоколы дают полиморфизм.

И теперь, немного синтаксического сахара, который упрощает написание и чтение кода в определённых ситуациях.
[<:a, 1>] можно писать так: [a: 1]

Точно так же, часто приходиться писать такие конструкции, как:
func3(func2(func1(list))), несмотря на то, что вызов функции func1 произойдёт первым, мы пишем вначале func3 или должны вводить переменные, как в этом случае:

C помощью оператора pipeline (|>) мы можем переписать наш пример так:

В библиотеке elixir-а стандартизировано субъект идёт первым аргументом. И это даёт возможность с помощью |> оператора, который подставляет результат предыдущего действия как первый аргумент функции в следующий вызов, писать более понятный, компактный и последовательный код.

Ещё, мы можем упростить этот пример, используя curry или partials в простых случаях:

Я думаю, Elixir будет интересен erlang-разработчикам, которые хотят улучшить качество своего кода, продуктивность, и опробовать метапрограммирование в действии. Аналогично, разработчики с других языков и платформ также проявят к нему интерес. Например те, кто хотели бы опробовать BeamVM, но не решались из-за синтаксиса erlang-а или сумбура в его библиотеках. Здесь важным достоинством elixir-а является стандартизированная и компактная стандартная библиотека(Standard Library).

Источник

Сказочный портал