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. В репозитории опубликована отличная обзорная документация. Ролик ниже иллюстрирует небольшой пример работы языка: