Главная
Новости
Строительство
Ремонт
Дизайн и интерьер

















Яндекс.Метрика





Elixir (язык программирования)


Elixir — функциональный, распределённый язык программирования общего назначения, который работает на виртуальной машине Erlang (BEAM). Построен поверх Erlang, что обеспечивает распределённость, отказоустойчивость, исполнение в режиме мягкого реального времени, метапрограммирование с макросами и полиморфизмом, реализованным через протоколы. Использует Erlang/OTP для работы с деревьями процессов.

Создан Жозе Валимом (José Valim), ранее являвшимся одним из основных разработчиков фреймворка Ruby on Rails и сооснователем компании Plataformatec. Его целью было включить более высокую расширяемость и производительность в Erlang VM, сохраняя совместимость с инструментами и экосистемой Erlang.

Возможности

Программы компилируются в байт-код для виртуальной машины Erlang (BEAM). Каждый элемент программы является выражением, функции языка Erlang могут быть вызваны без влияния на время исполнения из-за компиляции байт-кода в Erlang и наоборот.

Метапрограммирование дает возможность прямого манипулирования абстрактным синтаксическим деревом (АСД). Полиморфизм, реализованный через механизм протоколов, которые, как и в Clojure, обеспечивают механизм диспетчеризации (не стоит путать с множественной диспетчеризацией). Параллельное программирование — без разделения ресурсов, через передачу сообщений (модель акторов). На практике упор делается на рекурсии и функциях высшего порядка вместо применения циклов, основанных на побочных эффектах. Для реализации простого параллелизма использованы механизмы Erlang с упрощённым синтаксисом (например, Task).

Реализованы ленивые вычисления и асинхронные коллекции с потоками, сопоставление с образцом.

Язык поддерживает Unicode и UTF-8-строки. Реализована поддержка документирования кода по синтаксису напоминающая строки документации языка Python, но в формате Markdown.

Описание языка

Типы данных

На низком уровне Elixir использует примитивные типы, доступные в виртуальной машине Erlang. Так, список — всего лишь упорядоченный набор значений.

Elixir имеет следующие встроенные типы данных (см. также типы данных Erlang):

  • Целые произвольной точности;
  • Числа с плавающей запятой;
  • Атомы;
  • Интервальные типы (англ. ranges);
  • Регулярные выражения;
  • Идентификаторы процессов (PID) и портов;
  • Ссылки;
  • Кортежи;
  • Списки;
  • Отображения (англ. maps);
  • Бинарные данные (англ. binaries);
  • Функции.

На основе этих примитивных типов в Elixir в частности построены строки и структуры.

Модули

На основе встроенных типов данных можно строить более высокоуровневые абстракции. Для построения абстракций данных в языке функционального программирования Elixir используются модули. Например, Keyword является модулем Elixir, а его реализация основана на списке кортежей, и, естественно, с Keyword можно работать и как со списком. Модули являются «чистыми» и не содержат собственного состояния как, например, объекты в языках, использующих ООП.

Например, аналогом "строка".downcase из Ruby в Elixir будет: String.downcase("строка"). Обычно экземпляр абстракции передаётся в функции модуля как первый аргумент.

Модули содержат функции, позволяющие создать абстракцию, делать запросы, а также модифицировать её (путём создания нового экземпляра). Следует заметить, что абстракции не могут содержать скрытых данных — они прозрачны для пользователей модуля. В то же время, модули могут содержать внутренние функции (определяемые с помощью defp), которые недоступны из других модулей.

Сравнение с Erlang

Elixir был задуман как улучшение Erlang, в частности, значительного упрощения синтаксиса. Одним из основных отличий является возможность повторного присваивания значений переменных. В Elixir не требуется завершать каждую команду точкой (по примеру Пролога), так как выражения разделяются переводом строки и точкой с запятой (;). В Elixir не требуется экспортировать функции модуля, тогда как в Erlang по умолчанию все функции недоступны из других модулей, если не упомянуты в директиве -export. Тем самым, синтаксис Elixir больше похож на синтаксис Ruby.

Использование

Язык программирования Elixir используется для разработки веб-приложений с помощью полнофункциональной экосистемы веб-приложений Phoenix, а также HTTP-сервера Cowboy.

Примеры

Следующие примеры могут быть запущены в оболочке iex или могут быть сохранены в файле и запущены с помощью команды elixir <имя файла>.

Пример классической программы Hello world:

IO.puts "Hello World!"

Создание нового списка (List) на основе существующего с помощью спискового включения:

for n <- [1,2,3,4,5], rem(n,2) == 1, do: n*n #=> [1, 9, 25]

Сопоставление с образцом:

[1, a] = [1, 2] # a = 2 {:ok, [hello: a]} = {:ok, [hello: "world"]} # a = "world"

Оператор конвейера (англ. pipe):

"3" |> String.to_integer() |> Kernel.*(2) # 6

Бинарные данные и битовые строки:

bb = <<20, 19, 3>> # <<20, 19, 3>> <<b1, b2, b3>> = bb # <<20, 19, 3>> b1 # 20 <<a :: 4, b :: 4>> = << 254 >> # <<254>> a # 15 b # 14

где bb — переменная с двоичными данными из трёх байт b1, b2, b3 (показан синтаксис сопоставления с образцом), а из числа 254 с помощью сопоставления с образцом выделяются в отдельные переменные a и b биты с первого по четвёртый и с пятого по восьмой.

Модули:

defmodule Fun do def fib(0), do: 0 def fib(1), do: 1 def fib(n) do fib(n-2) + fib(n-1) end end

Порождение большого числа процессов в цикле:

for num <- 1..1000, do: spawn fn -> IO.puts("#{num * 2}") end

Асинхронное выполнение:

task = Task.async fn -> perform_complex_action() end other_action() Task.await task

Внутреннее представление кода:

quote do: (k = 1; k + 2) # в результате даёт {:__block__, [], [{:=, [], [{:k, [], Elixir}, 1]}, {:+, [context: Elixir, import: Kernel], [{:k, [], Elixir}, 2]}]}

Инструментарий

Для работы с проектами на Elixir: создания новых, управления зависимостями, компиляции, тестирования, запуска на выполнение — имеется утилита автоматизации (англ. build tool) под названием Mix. Например, команда mix new myproject создаёт новый проект по шаблону, в результате чего появляется каталог проекта (версия Mix 1.1.1):

myproject/ ├── config │ └── config.exs ├── .gitignore ├── lib │ └── myproject.ex ├── mix.exs ├── README.md └── test ├── myproject_test.exs └── test_helper.exs

Где config содержит конфигурацию приложения, lib — исходный код, tests — тесты, mix.exs — конфигурацию проекта.