Elixir — это стандартное OTP приложение, где-то на просторах гитхаба есть даже rebar плагин для компиляции эликсир кода. Т.е. путь интеграции простой — все приложения под Elixir, как и сам Elixir — это OTP приложения со всем вытекающим, а для компиляции есть rebar плагин. Так же, как из Elixir-а легко и просто вызывать Erlang код, так же и из Erlang-а легко и просто вызывать Elixir код. Единственное, что не интегрируется в erlang приложение напрямую — это использование Elixir-овских макро из Erlang кода по вполне понятным причинам.
НО: спрос на использование Elixir из Erlang-а сверхнизкий, потому что люди, которые садятся за Elixir в конечном итоге используют Erlang из Elixir-а из-за удобства, что есть в Elixir-е (это и mix и exrm и много других факторов, которые сделаны более удобно, чем аналогичные под Erlang), соответственно всё, что есть (rebar плагин) для обратной интеграции никак не поддерживается из-за спроса равного или стремящемуся нулю. А вот с другой стороны, где к чисто Erlang проектам прилагается mix.exs фаил встречается очень часто, при том, что в одной команде, которую я знаю некоторые разработчики настолько были в восторге от Elixir-а, что строили и тестировали Erlang(без единой строчки кода на Elixir) проекты с помощью mix-а и зависимости тянули с помощью mix-а.
Обладая опытом 3 лет профессиональной разработки на эрланге, и как минимум 1,5 годовым опытом использования эликсира, могу опровергнуть ещё одно утверждение(о документации уже опровергли).
«сложность получения помощи от сообщества»
Могу сказать о моём опыте: более отзывчивого сообщества я ещё пока не встречал, когда у меня была какая-то проблема, то в тот же день(или даже час) вместе с Jose Valim находил её причину и он исправлял на мастере эликсира, когда нам нужны были maps-ы ещё за 3 месяца до их официального релиза в эрланге — мы уже начали встраивать их в эликсир — по сути из-за того, что они нужны были мне в одном экспериментальном проекте на фирме.
Эликсир имеет свой компилятор из кода эликсир в AST, а из AST в AST эрланга, соответственно если и задачи у parse_transform и макро в эликсире схожие, то реализация никак не поверх parse_transform.
Если есть интерес о статье по метапрограммированию в эликсире, могу написать.
По мне, так руководство на официальном сайте (elixir-lang.com) за всё время было лучшим руководством по Elixir. Так что, для тех, кто читает по-английски ничего писать не надо. Я максимум думал над русской версией.
Я долго удивлялся, почему там нет ни одной критической и опровергающей записи в комментариях, при том, что рассказчик делает очень много фактических ошибок(начиная от персонала и наимом на работу иностранцев, заканчивая статусом Германии, как государства).
После этого, я наивно решил написать комментарий, предоставив немного фактической информации(комментарии огранничены размером), в которых он ошибался. К сожалению, мой комментарий за несколько дней так и не прошёл модерации, думаю и не пройдёт. Не верьте всему тому, что показывают там, где пресекают объективную критику.
Дополнил раздел по метапрограммированию («Everything is an expression»), добавил комментарии и добавил ещё пример с регулярными выражениями. Сейчас, надеюсь, раздел более понятен?
Да, рекорды, только я не знал, как они правильно переводятся(при написании была путанница с переводом типов данных на русский язык). Наверное проще было везде оставить английские названия. Исправил строчку с Enum-ом.
defimpl — макро, которое генерирует модуль: . (т.е. в нашем случае beam файл: Elixir.Access.Tree.beam )
Если создать свой протокол, то можно создать имплементации для всех встроенных типов, например списков, кортежей, цифр и так далее. Реализовать протоколоподобную систему можно и в erlang-е, как и метапрограммирование, например с помощью parse transform. В elixir в принципе нет ничего того, что нельзя делать в erlang-е, вопрос в том, сколько усилий в конечном счёте — это занимает. И как показывает практика, никто этого не делает в elrang-е.
«Раздел «Everything is an expression» что-то не понял вообще.» =>
Я завтра дополню раздел, поподробнее прокоментирую каждый кусок кода и напишу, что происходит, и покажу возможности на чуть более интересном примере. Спасибо за комментарий, буду исправлять.
На мой взгляд, это не ошибка в дизайне, а наоборот правильное решение, по причинам описанным выше.
Я думаю сравнение строготипизированного haskell-я(и других функциональных языков строгой типизации) с языком с динамической типизации elixir-ом(построенным над BeamVM изначально с динамической типизацией) бессмысленно.
sum = foldl + 0
Такой код, и подобный стиль в elixir или erlang будет вести к множеству runtime ошибок, так как если в haskell компилятор будет всё проверять вовремя компиляции, то под BeamVM этого не делается. Строить строготипизированный язык поверх BeamVM тоже не самое благоразумное решение. Строгая типизация усложняет многие механизмы, заложенные в BeamVM, такие как hot code loading и многие другие. Скорее это уже будет новая VM(когда-нибудь).
Вторая проблема, это функции, с разным кол-вом аргументов, например:
def mysum(list, acc // 0) do
....
end
Создаёт две функции: mysum/1 и mysum/2 и тогда curring без указания arity функции не имеет смысла, т.е. так или иначе нужно указать аргументы, которые ожидает функция.
Тогда, в elixir-е тоже самое мы можем написать так:
sum = List.foldl(&1, 0, &1 + &2)
sum.([1,2,3,4,5])
Либо вот так, если curring идёт последним аргументом:
sum = :lists.foldl(&1 + &2 0, &1)
sum.([1,2,3,4,5])
И в данном случае, практически не имеет значения, будем ли делать curry первым или вторым способом.
А из-за причин указанных выше(стандартизации не только для структур данных, но и для много другого, как соединения, файлы, где тоже можно делать pipelining), то я думаю, что в случае elixir-а — это очень правильное решение, так как не теряя качеств в связи с особенностями BeamVM это даёт описанные выше преимущества.
В любом случае, не считаю поводом отказываться от эликсира, лишь потому что другие языки делают это по-другому, не пытаясь разобраться в деталях, почему. Возможно и я ошибаюсь в разнице между строготипизированными и динамическими функциональными языками в данном случае, если это так, то поправьте меня. Но если мои рассуждения верны, то это никак не ошибка в дизайне elixir.
На мой взгляд, удобнее как раз использовать первый аргумент для субъекта, так как:
1) Если использовать последний аргумент, то это может вводить в замешательство, особенно при использовании с необязательными аргументами. Или, например в таких случаях, как в эрланге: element(N, Tuple) и setelement(Index, Tuple1, Value), где в первой функции субъект идёт последним аргументом, а во второй идёт по середине(?!).
2) В библиотеках при работе с файлами, соединениями часто субъект идёт первым аргументом. Например, мы не пишем:
file:open(Options, Filename) (в эрланге)
Хотя здесь и очевидно, что имя файла является субъектом.
2) И на мой взгляд, удобнее писать, когда функция идёт последним аргументом(хоть и не привычно), особенно когда тело функции является более длинным, чем половина строки(что очень часто встречается), пример:
:lists.foldl(fn({a, b}, acc) ->
c = case a > b do
true -> a * 2
false -> b * 3
end
acc + c + 1
end, 0, [{1,2},{3, 4}])
Если посмотреть на функцию, то неудобно, что между самой функцией, названием и аргументами более 5 строк, а тот же самый вариант с эликсировской стандартной библиотекой выглядит так:
List.foldl([{1, 2}, {3, 4}], 0, fn({a, b}, acc) ->
c = case a > b do
true -> a * 2
false -> b * 3
end
acc + c + 1
end)
Мы видим в одной строчке название функции и аргументы в одной строке.
НО: спрос на использование Elixir из Erlang-а сверхнизкий, потому что люди, которые садятся за Elixir в конечном итоге используют Erlang из Elixir-а из-за удобства, что есть в Elixir-е (это и mix и exrm и много других факторов, которые сделаны более удобно, чем аналогичные под Erlang), соответственно всё, что есть (rebar плагин) для обратной интеграции никак не поддерживается из-за спроса равного или стремящемуся нулю. А вот с другой стороны, где к чисто Erlang проектам прилагается mix.exs фаил встречается очень часто, при том, что в одной команде, которую я знаю некоторые разработчики настолько были в восторге от Elixir-а, что строили и тестировали Erlang(без единой строчки кода на Elixir) проекты с помощью mix-а и зависимости тянули с помощью mix-а.
Можно будет тогда c 1.7 версии и нам connector написать.
А когда планируете, что версия 1.7 будет опубликована/готова?? Есть уже предположительные сроки?
«сложность получения помощи от сообщества»
Могу сказать о моём опыте: более отзывчивого сообщества я ещё пока не встречал, когда у меня была какая-то проблема, то в тот же день(или даже час) вместе с Jose Valim находил её причину и он исправлял на мастере эликсира, когда нам нужны были maps-ы ещё за 3 месяца до их официального релиза в эрланге — мы уже начали встраивать их в эликсир — по сути из-за того, что они нужны были мне в одном экспериментальном проекте на фирме.
Если есть интерес о статье по метапрограммированию в эликсире, могу написать.
После этого, я наивно решил написать комментарий, предоставив немного фактической информации(комментарии огранничены размером), в которых он ошибался. К сожалению, мой комментарий за несколько дней так и не прошёл модерации, думаю и не пройдёт. Не верьте всему тому, что показывают там, где пресекают объективную критику.
defimpl — макро, которое генерирует модуль: . (т.е. в нашем случае beam файл: Elixir.Access.Tree.beam )
Если создать свой протокол, то можно создать имплементации для всех встроенных типов, например списков, кортежей, цифр и так далее. Реализовать протоколоподобную систему можно и в erlang-е, как и метапрограммирование, например с помощью parse transform. В elixir в принципе нет ничего того, что нельзя делать в erlang-е, вопрос в том, сколько усилий в конечном счёте — это занимает. И как показывает практика, никто этого не делает в elrang-е.
«Раздел «Everything is an expression» что-то не понял вообще.» =>
Я завтра дополню раздел, поподробнее прокоментирую каждый кусок кода и напишу, что происходит, и покажу возможности на чуть более интересном примере. Спасибо за комментарий, буду исправлять.
Я думаю сравнение строготипизированного haskell-я(и других функциональных языков строгой типизации) с языком с динамической типизации elixir-ом(построенным над BeamVM изначально с динамической типизацией) бессмысленно.
Такой код, и подобный стиль в elixir или erlang будет вести к множеству runtime ошибок, так как если в haskell компилятор будет всё проверять вовремя компиляции, то под BeamVM этого не делается. Строить строготипизированный язык поверх BeamVM тоже не самое благоразумное решение. Строгая типизация усложняет многие механизмы, заложенные в BeamVM, такие как hot code loading и многие другие. Скорее это уже будет новая VM(когда-нибудь).
Вторая проблема, это функции, с разным кол-вом аргументов, например:
Создаёт две функции: mysum/1 и mysum/2 и тогда curring без указания arity функции не имеет смысла, т.е. так или иначе нужно указать аргументы, которые ожидает функция.
Тогда, в elixir-е тоже самое мы можем написать так:
Либо вот так, если curring идёт последним аргументом:
И в данном случае, практически не имеет значения, будем ли делать curry первым или вторым способом.
А из-за причин указанных выше(стандартизации не только для структур данных, но и для много другого, как соединения, файлы, где тоже можно делать pipelining), то я думаю, что в случае elixir-а — это очень правильное решение, так как не теряя качеств в связи с особенностями BeamVM это даёт описанные выше преимущества.
В любом случае, не считаю поводом отказываться от эликсира, лишь потому что другие языки делают это по-другому, не пытаясь разобраться в деталях, почему. Возможно и я ошибаюсь в разнице между строготипизированными и динамическими функциональными языками в данном случае, если это так, то поправьте меня. Но если мои рассуждения верны, то это никак не ошибка в дизайне elixir.
1) Если использовать последний аргумент, то это может вводить в замешательство, особенно при использовании с необязательными аргументами. Или, например в таких случаях, как в эрланге: element(N, Tuple) и setelement(Index, Tuple1, Value), где в первой функции субъект идёт последним аргументом, а во второй идёт по середине(?!).
2) В библиотеках при работе с файлами, соединениями часто субъект идёт первым аргументом. Например, мы не пишем:
file:open(Options, Filename) (в эрланге)
Хотя здесь и очевидно, что имя файла является субъектом.
2) И на мой взгляд, удобнее писать, когда функция идёт последним аргументом(хоть и не привычно), особенно когда тело функции является более длинным, чем половина строки(что очень часто встречается), пример:
Если посмотреть на функцию, то неудобно, что между самой функцией, названием и аргументами более 5 строк, а тот же самый вариант с эликсировской стандартной библиотекой выглядит так:
Мы видим в одной строчке название функции и аргументы в одной строке.
Ваш пример можно написать так:
Или так с использованием partials: