Erlang является уникальной по своим возможностям платформой, и не смотря на это, язык до сих пор является экзотикой. Причин существует несколько. Например, тугая арифметика, непривычность синтаксиса, функциональность. Это не недостатки. Это просто вещи, с которыми большинство программистов не могут или не хотят работать.
Несколько дней назад Jose Valim опубликовал в своем репозитории проект языка, построенного поверх Erlang. Этот язык обладает простой объектной моделью и Ruby-подобным синтаксисом. Под катом выжимки из документации и видео, демонстрирующее простой пример.
disclaimer: %username%, прежде чем делать выводы насчет того, что умеет, а что не умеет elixir, просьба глазами пройтись хотя бы по readme.
Elixir — язык программирования, работающий поверх Erlang. Как Erlang, это — функциональный язык со строгими вычислениями, однократным присвоением и динамической типизацией, созданный, чтобы поддерживать распределенные, отказоустойчивые, безостановочные приложения с горячей заменой кода. Elixir позволяет Вам вызывать модули Erlang без необходимости преобразовать типы данных, поэтому нет никакой потери в производительности при вызове кода Erlang.
Основное различие между Elixir и Erlang — синтаксис и объектная ориентированность. Elixir обеспечивает очень простую объектную модель и синтаксис, большей частью основанный на Ruby.
В настоящее время главной задачей является разработка стандартной библиотеки. Большая часть существующей стандартной библиотеки написана на самом Elixir, и Вам не нужно знать Erlang, чтобы внести свой вклад в ее развитие. Достаточно будет знакомства с принципами OTP.
Чтобы начать работу, для начала нужно клонировать репозиторий к себе на компьютер, скомпилировать и проверить его:
Комментарии в Elixir, как и в Erlang, обозначаются через “%”:
Далее, “% =>” показывают значение выражения:
Elixir поддерживает целые и дробные числа:
Как в Ruby, любая конструкция является объектом. Мы можем вызывать методы у чисел:
Атомы в Elixir называются Symbols (как в Ruby). Но синтиксис позаимствован у Lisp (Jose объяснил это в твиттере тем, что хочет ":" использовать в словарях):
Списки являются наиболее полезной структурой в Elixir (как и в любом другом функциональном языке), могу содержать все, что угодно и имеют набор методов:
Списки в Erlang и Elixir реализованы как связные списки, поэтому предварительное добавление элементов происходит намного быстрее, чем последующее:
Настоящую силу списков получаешь, когда используешь их вместе с функциями
Строки в Erlang представлены списком символов:
Это накладно, поскольку каждый символ занимает 8 байт памяти (не бит!). Elixir реализует строки, в виде utf8 бинарных строк:
Это существенное изменение. Строки являются единственными объектами, требующими преобразования:
Наконец, строки поддерживают интерполяцию:
Функции являются важной частью Elixir, как и любого другого функционального языка. Функции можно создавать с помощью «do» или "->":
Как и Erlang, Elixir поддерживает Pattern matching и единичное присваивание.
Как и в Eralng, pattern matching используется в сигнатурах функций:
Вызов методов Erlang весьма тривиален:
Объектная модель Elixir имеет некоторые аспекты:
Это описание малой части возможностей Elixir. В репозитории опубликована отличная обзорная документация. Ролик ниже иллюстрирует небольшой пример работы языка:
Несколько дней назад Jose Valim опубликовал в своем репозитории проект языка, построенного поверх Erlang. Этот язык обладает простой объектной моделью и Ruby-подобным синтаксисом. Под катом выжимки из документации и видео, демонстрирующее простой пример.
disclaimer: %username%, прежде чем делать выводы насчет того, что умеет, а что не умеет elixir, просьба глазами пройтись хотя бы по readme.
Elixir — язык программирования, работающий поверх Erlang. Как Erlang, это — функциональный язык со строгими вычислениями, однократным присвоением и динамической типизацией, созданный, чтобы поддерживать распределенные, отказоустойчивые, безостановочные приложения с горячей заменой кода. Elixir позволяет Вам вызывать модули Erlang без необходимости преобразовать типы данных, поэтому нет никакой потери в производительности при вызове кода Erlang.
Основное различие между Elixir и Erlang — синтаксис и объектная ориентированность. Elixir обеспечивает очень простую объектную модель и синтаксис, большей частью основанный на Ruby.
В настоящее время главной задачей является разработка стандартной библиотеки. Большая часть существующей стандартной библиотеки написана на самом Elixir, и Вам не нужно знать Erlang, чтобы внести свой вклад в ее развитие. Достаточно будет знакомства с принципами OTP.
Чтобы начать работу, для начала нужно клонировать репозиторий к себе на компьютер, скомпилировать и проверить его:
$ git clone https://github.com/josevalim/elixir.git $ cd elixir $ make test $ bin/elixir -v Elixir 0.1.0
Комментарии в Elixir, как и в Erlang, обозначаются через “%”:
% This is a commented line
Далее, “% =>” показывают значение выражения:
1 + 1 % => 2
Elixir поддерживает целые и дробные числа:
2 + 15 % => 17 - 13 * 10 % => -130 1986 - 1985 % => 1 5 / 2 % => 2.5 4 / 2 % => 2.0
Как в Ruby, любая конструкция является объектом. Мы можем вызывать методы у чисел:
-1.abs % => 1 5.div(2) % => 2 %surprise ! 1.+(2) % => 3
Атомы в Elixir называются Symbols (как в Ruby). Но синтиксис позаимствован у Lisp (Jose объяснил это в твиттере тем, что хочет ":" использовать в словарях):
'atom 'Atom 'atom_without_spaces '"Atom with Spaces"
Списки являются наиболее полезной структурой в Elixir (как и в любом другом функциональном языке), могу содержать все, что угодно и имеют набор методов:
% Some list with elements ['atom, 1, 2, 3, { 'some, 'tuple }] % An empty list [] [1, 2, 3].length % => 3 ['a, 'b, 'c][1] % => 'b [1, 2, 3] + [4, 5, 6] % => [1,2,3,4,5,6]
Списки в Erlang и Elixir реализованы как связные списки, поэтому предварительное добавление элементов происходит намного быстрее, чем последующее:
list = [2,3,4] % Don't do this: [1] + [2,3,4] % => [1,2,3,4] [0,1] + [2,3,4] % => [0,1,2,3,4] % Do this instead: [1|list] % => [1,2,3,4] [0,1|list] % => [0,1,2,3,4]
Настоящую силу списков получаешь, когда используешь их вместе с функциями
[1, 2, 3].map do (x) x * 2 end % => [2, 4, 6] [1, 2, 3].foldl 0, do (x, acc) acc + x end % => 6
Строки в Erlang представлены списком символов:
"hello" == [104, 101, 108, 108, 111]
Это накладно, поскольку каждый символ занимает 8 байт памяти (не бит!). Elixir реализует строки, в виде utf8 бинарных строк:
% The famous "hello world" string "hello world" % A string converted to its underlying binary: "hello".to_bin % => <<[104, 101, 108, 108, 111]>> % A string converted to a char list: "hello".to_char_list % => [104, 101, 108, 108, 111] % Strings are UTF-8 "Arrow ⇧ up".length % => 10
Это существенное изменение. Строки являются единственными объектами, требующими преобразования:
% Converting a string_from_erlang to Elixir's String String.new string_from_erlang % Where string_from_erlang is either a binary: <<[104, 101, 108, 108, 111]>> % Or a char_list: [104, 101, 108, 108, 111] % Converting a string_from_elixir to Erlang "string_from_elixir".to_bin "string_from_elixir".to_char_list
Наконец, строки поддерживают интерполяцию:
"string #{'with} interpolation" % => "string with interpolation" "1 + 1 = #{1 + 1}" % => "1 + 1 = 2"
Функции являются важной частью Elixir, как и любого другого функционального языка. Функции можно создавать с помощью «do» или "->":
my_function = do 1 + 2 end my_function() % => 3 another_function = -> 1 * 2 end another_function() % => 2
Как и Erlang, Elixir поддерживает Pattern matching и единичное присваивание.
% Let's bound the variable x to 'foo x = 'foo % Now let's match a tuple with other tuple. % Since x is already bound, we are comparing x with 'baz and it will fail: { x, y } = { 'baz, 'bar } % In this case, we compare 'x with 'foo and it matches. % Since y is unbound, we assign 'bar to it: { x, y } = { 'foo, 'bar } x % => 'foo y % => 'bar [h|t] = [1,2,3] h % => 1 t % => [2,3] % Raises an error because h was already assigned to 1 and 1 does not match 2 [h|t1] = [2,3,4]
Как и в Eralng, pattern matching используется в сигнатурах функций:
module Math def fibonacci(0) 0 end def fibonacci(1) 1 end def fibonacci(n) fibonacci(n - 1) + fibonacci(n - 2) end end Math.fibonacci(0) % => 0 Math.fibonacci(1) % => 1 Math.fibonacci(3) % => 2 Math.fibonacci(10) % => 55
Вызов методов Erlang весьма тривиален:
% Accessing the is_atom BIF from Erlang. % This is the same as `is_atom(foo)` in Erlang. Erlang.is_atom('foo) % => true % Accessing the function delete from module lists. % This is the same as `lists:member(1, [1,2,3])` in Erlang. Erlang.lists.member(1, [1,2,3]) % => true
Объектная модель Elixir имеет некоторые аспекты:
- Динамический выбор реализации — когда вызывается метод, объект сам выбирает, какой код выполнить
- Mixin'ы — объекты не содержат методов. Все методы запакованы в модули, которые подмешиваются в объекты.
- Инкапсуляция — методы могут быть public, protected или private.
- Открытая рекурсия — объекты имеют специальную переменную self, которая позволяет вызвать другие методы объекта не затрагивая цепочку вызовов.
- Рефлексия — Elixir способен просматривать и модифицировать структуру объекта во времени исполнения.
object Person def constructor(name, age) { 'name: name, 'age: age } end def name @name end def age @age end def name(value) self.set_ivar('name, value) end end person = Person.name('john, 24) another_person = person.name('john_doe) person.name % => 'john person.age % => 24 another_person.name % => 'johh_doe another_person.age % => 24
Это описание малой части возможностей Elixir. В репозитории опубликована отличная обзорная документация. Ролик ниже иллюстрирует небольшой пример работы языка: