Elixir

    Erlang является уникальной по своим возможностям платформой, и не смотря на это, язык до сих пор является экзотикой. Причин существует несколько. Например, тугая арифметика, непривычность синтаксиса, функциональность. Это не недостатки. Это просто вещи, с которыми большинство программистов не могут или не хотят работать.

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

    Share post

    Similar posts

    Comments 80

      0
      Спасибо. Интересная статья.
        0
        Это не совсем статья. Хотелось завлекалочку написать.
        –18
        Хуита
          –3
          Теперь вместо того, что бы создавать переносимый код какие-то идиоты будут писать на рубиподобном гавне, только из-за того, что другой закостенелым мозгом прилип к объектно-ориентированному программированию. К сожалению еще один бесполезный проект в тонущем гавне второго математического кризиса.
            +1
            Да ладно прям…

            Вон Scala например — язык на основе Java JVM, но с функциональным уклоном… Тоже будем кричать «Не нужен»?
              0
              С другой стороны, позитивный момент в том что все больше интереса к erlang vm и его принципам. Да, эти все языки-надстройки скорее лишний барьер на пути к ерлангу, но про позитивные индикаторы не стоит забывать.
              +5
              Кто-нибудь объяснит мне, зачем оно вообще нужно?
                +3
                Потому что синтаксис эрланга кажется многим несколько своеобразным.
                  +6
                  Синтаксис руби тоже многим кажется своебразным :)
                    0
                    В большинстве своем тех, кому не нравится синтаксис Erlang, удовлетворит синтаксис Ruby.
                    +2
                    Ох не то слово — скрестили смолтолк с паскалем, блин :) Вот бы кто-нибудь замутил язык для Erlang VM на базе питона…
                      0
                      Не на базе питона, но похож на него — efene.tumblr.com marianoguerra.com.ar/efene/
                        0
                        Спасибо посмотрю. Обидно, что вообще ниразу в гугле не всплывает.

                        А не знаете ничего о его практическом использовании? Коммерческие или хотя-бы opensource проекты?
                        0
                        Мое мнение что синтаксис у Erlang`а простой.
                        Да, может поначалу немного странноват, но ко всему привыкаешь.
                        0
                        Меня вот тут убивает открывающий апостроф без закрывающего — это ужастно.
                        Например как мне задать вот такой атом 'aa,bb' с запятой внутри? И как с ним не запутаться?
                          0
                          Эти синтаксис атомов в лиспе. Не помню, зачем такое нужно было делать, но автор упоминал.

                          Что насчет вашего примера, то вот такой вариант будет работать:
                          '"aa,bb"
                          


                          Насколько это красиво, другой вопрос.
                        +3
                        Да тут не только на синтаксис посягнули… Какие нафик объекты в Эрланге? :\
                          +1
                          Да нормальный там синтаксис. Но тут же не только синтаксис добавили, они ж еще и объекты туда воткнули зачем-то.
                            0
                            Так я и не утверждал обратного. Но у некоторых не получается понять, как без ООП в их привычном понимании (в виде java, c# и тому подобного) можно проектировать и писать большие системы. На rsdn некоторое время назад был довольно эпический спор на эту тему.
                              +1
                              Ну так значит и erlang этим людям не нужен, если они не в состоянии понять)
                        –1
                        Почему бы не писать имя автора по-русски?
                        «Хозе Валим (José Valim) опубликовал в своём...»
                          +1
                          Спасибо большое, меня проект заинтересовал, возможно для меня это будет переходной точкой к erlang.
                            –1
                            Согласен. Спасибо, что привели основы синтаксиса Erlang'a и Elixir'a.
                            0
                            Весьма занятно… Параллелить главное тоже умеет))

                            Есть, кстати, еще Reia reia-lang.org/ вроде тоже немного похоже
                              0
                              Reia не умеет работать с #record{}-ами
                              0
                              Добавьте тег велосипеды
                                +1
                                поправьте: «Mixin'ы — объекты не содержать методов. „

                                Вообще интересно.
                                С эрлангом всегда не хватало простого
                                list.map( x => x*x ).
                                весь этот fun...end только мешается.

                                Но вот внесение состояния (объекты ) это разрушает основной принцип ФП. И тогда вообще не понятно причем тут единстевнное присвание.
                                  0
                                  Эти объекты — синтаксический сахар. Они скрывают необходимость использования отдельной структуры для передачи в различные функции:
                                  
                                  %Erlang
                                  Person = person:find(john),
                                  Modified = person:set(name, john_doe, Person)
                                  true = person:save(Modified)
                                  

                                  
                                  %Elixir
                                  In Elixir, this would be written as:
                                  person = Person.find('john)
                                  modified = person.set('name, 'john_doe)
                                  true = modified.save
                                  


                                  Изменение свойств объекта возвращает новую структуру, как и в Erlang:
                                  
                                  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.new('john, 24)
                                  another_person = person.name('john_doe)
                                  
                                  person.name % => 'john
                                  person.age  % => 24
                                  
                                  another_person.name % => 'johh_doe
                                  another_person.age  % => 24
                                  
                                    +1
                                    Тогда отставить тревогу, пошел играться.

                                    Добавте эти строчки в обзор, пожалуйста, они упрощают понимание:

                                    Эти объекты — синтаксический сахар. Они скрывают необходимость использования отдельной структуры для передачи в различные функции:

                                    Изменение свойств объекта возвращает новую структуру, как и в Erlang:
                                      0
                                      А потом мы забудем, что есть возможность multidispatch'а… Благими намерениями…
                                  0
                                  «Elixir способен просматривать и модифицировать структуру объекта во времени исполнения.»

                                  seriously?
                                    +1
                                    Я вчера с Хосе Валимом поработал немного на тему пригодности elixir внутри живых проектов. Посмотрим — может попробую приткнуть в erlyvideo.
                                      0
                                      А напишите потом впечатления от языка?
                                        0
                                        Да, конечно отпишусь.
                                          0
                                          Простите, и как язык?
                                      0
                                      Занятно, занятно…
                                      Сам Эрланг то страшен как атомная война, а вот с его VM давно хотелось поиграть, уж больно интересные вещи умеет.

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

                                      Вопрос: были другие попытки завести приличный язык под Erlang VM(знаю, у неё есть собственное название — не могу вспомнить). Что-то другое Ruby подобное и LISP. Я верно понимаю, что оба они полумёртвые и промышленного применения не имеют?
                                        +3
                                        Вот я до сих пор пытаюсь понять, в чем страшность Erlang? Где именно начинается непонимание?
                                          +1
                                          Нужно отличать объективные и субъективные вещи.

                                          Erlang позволяет легко писать гибкие распределенные системы. Это объективная реальность.
                                          Я понимаю синтаксис Eralng, и он мне нравится. Это субъективная реальность, которая применима ко мне, но не применима к Васе из Челябинска.
                                            0
                                            Это все понятно, но вопрос вот в чем: где начинается затык у Васи из Челябинска?
                                            +1
                                            1. Отсутствие нормальных структур данных с именованными полями. Всё впихивается в списки и кортежи.

                                            2. Как следствие первого — паттерн-матчинг основное средство работы со структурами. В учебных примерах всё красиво, но реальный код, который видел в репозитариях проектов мягко говоря напрягает. В своём проекте такого ниразу не хочется.

                                            3. Зависисмость от знаков препинания.

                                            Как следствие уже три раза начинал ковырять учебник на оф. сайте и бросал через пару глав. Становилось очевидно, что 80% усилий идут не на осознание соответствующих идей а на парсинг кода. Даже с хаскелем и F# не настолько всё плохо.
                                              +2
                                              1. records? (они, конечно, не идеал, но задачу именованных полей решают весьма сносно).
                                              2. И как следствие, я нахожу pattern matching по records весьма удобным. Можно примеры кода который напрягает?
                                              3. Вас напрягает зависимость от знаков препинания в натуральном языке? В erlang, как по мне, весьма логичная схема. Если думать о ф-циях как о предложениях, все становится на свои места. Мы же не ставим точку посреди предложения? Коньюктивы отображаем как запятые? Ну а точка с запятой — это «или» — что то вроде «Мы можем поступить так; или можно пойти другим путем». С этой аналогией мне в свое время стало легко вкуриться в синтаксис.

                                              learnyousomeerlang.com видели?
                                                0
                                                1. Ага, и правда есть… В предпоследнем разделе тьюториала. Я бросил раньше. Судя по тому, что нагуглилось они сильно перегружены каким-то синтаксическим мусором при использовании.
                                                2. Да вот жеж ведь!
                                                3. Наверно я просто избалован Scala/Groovy/Python, но меня раздражает необходимость лишний раз что-то вводить в очевидных местах. Кроме того это потворствует попыткам втыкать по несколько конструкций на строку :)
                                                  0
                                                  я тебе сразу скажу: код, который по ссылке про Comet приложение сдохнешь отлаживать.

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

                                                  Иначе говоря, код который по ссылке явно не эталон. Уже не говоря про некоторые остальные тонкости, делающие его поддержку мучительной.

                                                  Что до синтаксического мусора, то действительно не всё сделано минимально, впрочем гораздо более высокоуровневая семантика паттерн-матчинга компенсирует неидеальность синтаксиса, что в итоге в моей практике приводит к коду, который в 5-100 раз компактнее, чем аналог на джаве.
                                                    0
                                                    Так если в учебную статью постят говнокод что-то не отлаживаемое, что будет когда «проект надо было сдать вчера а у нас 50 ошибок в трекере»?

                                                    Ну, можно ещё с C++ сравнить :) Да и вообще компактность шутка сложная, в Java большая часть многословности тоже не от ограничений языка, а от принятого стиля программирования.
                                                0
                                                1. А рекорды чем не угодили? При всем при этом они остаются всего лишь сахаром. Действительно списков и кортежей достаточно. Но рекорды есть и их даже матчить можно. В реальных проектах все нормально.

                                                3. Как это зависимость? Вы не можете разобраться, где ставить ",", где ";" а где "."?
                                                  0
                                                  Меня лично напрягает то что ',' и ';' сепараторы, а не терминаторы (как в C# например).

                                                  то есть получать ошибку тут:
                                                  A = a(),
                                                  B = b(),
                                                  .
                                                  не очень то приятно.

                                                  А вообще на мой взгляд эрланг хорошие вещи у пролога позаимствовал.
                                                    0
                                                    Здесь терминатор — точка ".".
                                                    А "," и ";" разделители.

                                                    Вообще хорошо было бы не ставить запятую в конце строки, либо разрешить ставить ее перед точкой — чтобы все строки внутри функции выглядели одинаково.

                                                    Хотя потом привыкаешь, что последняя запятая не нужна — как в натуральных языках.
                                                      0
                                                      Я про то же, выглядит красиво,
                                                      но при добавлении \ обмене местами выражений иногда раздражает.
                                                  • UFO just landed and posted this here
                                                      0
                                                      Ответил выше.
                                                      0
                                                      Не понял насчёт «паттерн-матчинг основное средство работы со структурами»
                                                      Во-первых, это не единственное средство работы, во-вторых чего тут плохого?
                                                      Какой именно код не нравится?

                                                      К рекордам претензии совершенно другие и пока хороших способов решения нет.

                                                      Зависимость от знаков препинания — да, утомляет.
                                                        0
                                                        Мне вот все еще интересно, откуда выплывает утомление от знаков препинания?
                                                          0
                                                          От того, что при перестановке двух клозов местами, надо не забыть поменять знаки препинания.
                                                          В итоге лишние изменения в гит-репозитории, лишнее место для ошибок.

                                                          Знаки препинания в эрланге реально утомляют. Причем особено утомляет даже не ,; а то, что иногда почему-то становится нельзя ставить;
                                                            0
                                                            Примеры «иногда»?
                                                              0
                                                              case Frame#video_frame.codec of
                                                              h264 -> handle_h264(Frame);
                                                              aac -> handle_aac(Frame);
                                                              pcma -> handle_pcma(Frame)
                                                              end


                                                              удаляем клоз на pcma и получаем синтаксическую ошибку. В итоге в изменениях будет видно удаление 2-х строк, а не одной. Хорошего мало.
                                                                0
                                                                Но ведь это не про «почему-то», это же вполне ожидаемое поведение.
                                                                  0
                                                                  Ожидаемое с точки зрения уже существующего парсера.
                                                                  Тем не менее оно для меня очень нелогичное и неудобное.
                                                                    0
                                                                    Меня лично это момент ничуть не утомляет. Однако можно попробовать нестандартное форматирование?

                                                                    case Frame#video_frame.codec of
                                                                    h264 -> handle_h264(Frame)
                                                                    ; aac -> handle_aac(Frame)
                                                                    ; pcma -> handle_pcma(Frame)
                                                                    end
                                                                      0
                                                                      Это ж мозг наизнанку надо вывернуть.
                                                                      Лучший вариант — убрать лишние знаки. Например, питон обходится вообще без них и все отлично читается.
                                                                        0
                                                                        А племя мумба-юмба обходится даже без алфавита ;)
                                                                          0
                                                                          Они, наверное, на брейн-факе программируют — там тоже алфавит не нужен :)
                                                                      0
                                                                      мне кажется вообще, что эта проблема совсем не уникальная для erlang. switch/case statement не утомляет в C? или в сложных or/and конструкциях в условиях в любом языке нас же не удивляет что последний or или and оператор надо тоже удалить?

                                                                      По поводу последнего, представим такой код:

                                                                      if ( (flag & TCP_NOKIDDING) ||
                                                                      zlag < Z_LAG_THR ) {
                                                                      ...
                                                                      }


                                                                      предположим, последнее условее более не надо

                                                                      if (flag & TCP_NOKIDDING) {
                                                                      ..
                                                                      }


                                                                      сколько строчек поменяется в гите? правильно, тоже две.
                                                                        0
                                                                        switch(frame->codec) {
                                                                        case H264: handle_h264(frame); break;
                                                                        case AAC: handle_aac(frame); break;
                                                                        case PCMA: handle_pcma(frame); break;
                                                                        }


                                                                        Так человечнее
                                                                          0
                                                                          по сути ответа на пример с if'ом не было ;)
                                                                            0
                                                                            а человечнее имхо было бы сделать

                                                                            handle_frame(Frame),
                                                                            ..
                                                                            handle_frame(#video_frame{ codec = h264 } = Frame) ->
                                                                            ...
                                                                            ну и так далее по тексту

                                                                              0
                                                                              И схлопотать ровно те же проблемы с.; которые вполне можно решить по-другому на уровне парсера.
                                                                                0
                                                                                предложения как решить это на уровне парсера?
                                                                                  0
                                                                                  Очевидно при смене заголовка функции понимать, что клозы функции закончились. Тогда вместо точно можно будет обойтись;
                                                                                    0
                                                                                    А что если это была ошибка?

                                                                                    handle_frame(..) ->
                                                                                    ...;
                                                                                    handke_frame(..) ->
                                                                                    ...


                                                                                    В данный момент об ошибке сразу станет известно на этапе компиляции. В случае «умного парсера» — в лучшем случае на этапе тестов. В худшем — в продакшне когда function_clause вывалится в лог.
                                                                            0
                                                                            if ( (flag & TCP_NOKIDDING) ||
                                                                            zlag < Z_LAG_THR ) {
                                                                            ...
                                                                            }


                                                                            Если бы у меня был километровый if, то его проще переписать так:
                                                                            if (
                                                                            (flag & TCP_NOKIDDING)
                                                                            || zlag < Z_LAG_THR
                                                                            ) {
                                                                            ...
                                                                            }


                                                                            Чтобы в логе гита изменялись не все строки, а только строки, содержащие условие — то есть там где реально было изменение смысла.
                                                                              0
                                                                              case Frame#video_frame.codec of
                                                                              h264 -> handle_h264(Frame)
                                                                              ; aac -> handle_aac(Frame)
                                                                              ; pcma -> handle_pcma(Frame)
                                                                              end
                                                                                0
                                                                                Как вы поняли сами, это не решение, это просто перемещение проблемы с последней строки в первую :)

                                                                                Точно так же как раньше я не мог спокойно закомментировать последнюю строку, я сейчас не могу это сделать с первой.
                                                                                  0
                                                                                  /me умывает руки.
                                                                0
                                                                И вам тоже ответил выше :)
                                                          0
                                                            0
                                                            да, синтаксис чем-то похож на структуру английских предложений.
                                                            Но программисткий язык все же отличается от человеческого — с ним идет немного другая работа, поэтому он может немного отличаться.

                                                            Идеальный терминатор строки — это его отсутствие.
                                                            Наоборот, если выражение продолжается, то надо его продлевать и этот случай обозначать особенным образом. Потому что лишь 0.1% выражений приходится переносить на другую строку, все остальные нормально помещаются. Поэтому удобнее писать 1 раз на 1000 строк "\" в конце, чем в каждой строке ставить ",;.".
                                                            Единсвтенно, если не использовать выделение блоков отсутпами, то можно использовать слово end
                                                              –1
                                                              да ну, а в языке Си и не знали что нельзя делать сепаратор ";"
                                                            –1
                                                            Не вижу смысла в этом эликсире. Ну синтаксис поменяли, но семантика, то осталась функциональная, разве нет? Т.е. большинству людей всё равно будет слишком непривычно. Плюс синтаксис не соответствует семантике, т.е. даже для знакомых с ФП язык плох.
                                                              0
                                                              радует, что основной коммитер — Jose Valim :)

                                                              Only users with full accounts can post comments. Log in, please.