Введение в Эликсир Ланг
Опубликовано: 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
* Иди и выпей этот эликсир! – @Рбин *