Введение в Эликсир Ланг

Опубликовано: 2015-02-27

Введение в язык программирования Elixir (и почему он мне нравится)

Несколько месяцев назад я написал статью, знакомящую вас с Голангом и рассказывающую о том, почему он мне так понравился. Хотя я действительно все еще люблю его, в последнее время я играю с новым языком; Эликсир. Я купил книгу Programming Elixir и следил за ней. Я уже полюбил Эликсир и надеюсь показать вам, почему в этой статье.

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

Я много раз слышал, как люди говорят, что Elixir — это «Ruby для Erlang» и т. д. Эта теория не совсем неверна, но на самом деле, в основном это просто синтаксис Elixir, на который повлиял Ruby, поскольку он не разделяет много одинаковых программных конструкций. Конечно, он чем-то похож на Erlang, так как он построен поверх виртуальной машины Erlang и изначально дает нам прямой доступ к примитивам Erlang.

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

Установка

Если вы работаете на OSX, установка так же проста, как с помощью Homebrew:
~ brew update
~ brew install erlang
~ brew install elixir

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

~ elixir -v
> Elixir 1.0.2

Теперь, когда Эликсир установлен правильно, мы можем открыть Интерактивный Эликсир и поиграть с некоторыми основными распространенными типами.

Типы в Эликсире

Запустите Interactive Elixir REPL, введя
> iex

Переменные:

iex(1)> name = "rbin"
#=> "rbin"

Атомы:

В Эликсире атом — это константа, в которой его имя является собственным значением.
iex(2)> :this_is_an_atom
#=> :this_is_an_atom
iex(3)> :my_atom == :atom
#=> false

Кортежи:

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

iex(4)> tuple = {:hello, "world"}
#=> {:hello, "world"}
iex(5)> elem(tuple, 1)
#=> "world"

Списки:

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

iex(8)> list = [1, 2, :atom]
#=> [1, 2, :atom]
iex(9)> ["string"] ++ list
#=> ["string", 1, 2, :atom]
iex(10)> list ++ [31]
#=> [1, 2, :atom, 31]

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

iex(11)> hd(list)
#=> 1
iex(12)> tl(list)
#=> [2, :atom]

Анонимные функции:

В Elixir функции являются гражданами первого класса, то есть мы можем передавать функции в качестве аргументов другим функциям. Ниже мы определим переменную с именем add , содержащую функцию, которую мы затем передадим в качестве аргумента функции is_function/1 .

iex(14)> add = fn a, b -> a + b end
#Function<12.90072148/2 in :erl_eval.expr/5>

iex(15)> add.(13, 31)
#=> 44

iex(16)> is_function(add)
#=> true

Организация наших проектов (микс)

Эликсир поставляется с очень полезным инструментом под названием Mix. Mix — это инструмент сборки, который позволяет нам очень легко генерировать, организовывать, компилировать и тестировать наши проекты. Это также упрощает нам управление зависимостями. (Всегда деликатная тема!) Чтобы создать новый проект с помощью Mix, мы просто делаем следующее:
~ mix new myapp --module MyApp
Это создаст каталог с именем myapp с несколькими файлами внутри. Он также определит модуль MyApp внутри lib/myapp.ex .
* creating README.md
* creating .gitignore
* creating mix.exs
* creating config
* creating config/config.exs
* creating lib
* creating lib/myapp.ex
* creating test
* creating test/test_helper.exs
* creating test/myapp_test.exs


Your mix project was created successfully.
You can use mix to compile it, test it, and more:

cd myapp
mix test

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

Файл mix.exs — это основной файл, используемый для настройки нашего проекта, управления зависимостями и т. д. Мы получаем test/folder , в котором мы можем написать очень похожие на ruby ​​тесты для нашего проекта. Мы, конечно же, получаем lib/folder , который содержит исходные файлы нашего проекта. Если мы запустим тест микса в нашем приложении, мы получим следующее:
$ mix test
Compiled lib/myapp.ex
Generated myapp.app
.

Finished in 0.04 seconds (0.04s on load, 0.00s on tests)
1 tests, 0 failures

Randomized with seed 543313

параллелизм

Как и в Erlang, в Elixir для параллелизма используется модель «актер». Весь наш код выполняется внутри процессов , и эти процессы изолированы друг от друга. Мы можем создавать полностью параллельные программы в Эликсире, порождая Процессы и отправляя и получая сообщения между ними.

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

iex(1)> spawn(fn -> IO.puts 1 + 1 end)
#=> 2
#PID<0.55.0>

Как видите, мы породили процесс, который выдал 1 + 1, а также вернул его идентификатор процесса. Возврат этого идентификатора процесса полезен, так как мы можем присвоить его переменной и использовать для отправки сообщений процессу. Прежде чем мы это сделаем, нам нужно создать механизм получения для получения сообщений, которые мы отправляем процессу. (Мы можем продолжить и сделать это в нашем сеансе Interative Elixir , строка за строкой.)

Как только мы это сделали, мы можем создать процесс, который оценивает area_loop и назначит его pid .

pid = spawn(fn -> Geometry.area_loop() end)
#=> #PID<0.40.0>

Затем мы можем отправлять сообщения pid , с которыми будет совпадать наш предопределенный код, в зависимости от того, получает ли он атом :rectangle или атом :circle .

send pid, {:rectangle, 2, 3}
#=> Area = 6
# {:rectangle,2,3}

send pid, {:circle, 2}
#=> Area = 12.56000000000000049738
# {:circle,2}

Мы можем проверить, запущены ли процессы, используя Process.alive? функция.

Process.alive?(pid)
#=> false

Заключение

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

  • Это было легко понять, с синтаксисом, похожим на ruby , и примитивами, подобными Erlang.
  • За ним стоит фантастическое сообщество
  • Эта модель параллелизма мне знакома и очень эффективна.
  • Mix - это находка, и экономит МНОГО времени
  • Эликсир призывает нас все документировать
  • Это делает создание распределенных приложений гораздо менее запутанным полем битвы
  • Я вижу, что Эликсир идет ДОЛГИЙ путь.

Ресурсы

Некоторые ресурсы, которые я нашел очень полезными за короткое время изучения Эликсира:

  • http://elixir-lang.org/getting-started/introduction.html
  • https://pragprog.com/book/elixir/programming-elixir
  • https://teamgaslight.com/blog/the-best-resources-for-learning-elixir
  • http://exercism.io

* Иди и выпей этот эликсир! – @Рбин *