Elm или функциональное программирование для веб, понятное чайнику

    Недавно, просматривая интересные репозитории на github в поисках вдохновения я наткнулся на проект Elm — функциональный реактивный язык программирования, созданный для веб, потомок ML и Haskell. У меня нет большого опыта в функциональном программировании, но посмотрев посадочную страницу, я увлекся этим творением на несколько часов, позабыв о работе и окружающем мире. Меня сразу вдохновила та простота, которая, как мне казалось раньше не присуща функциональным языкам программирования.
    Еще раз повторюсь, что я не силен в функциональном программировании, плохо знаком с математическими концепциями, на которых оно строится и изучению Elm удлелил, пока что, не очень много времени. Я считаю, что лучше бы эту статью написал кто-то другой, более осведомленный, но, таковых не нашлось, а до тех пор, я решил возложить эту ношу на себя, быть может, моя статья поможет кому-то открыть для себя прелести функционального программирования для веб, или по новому взглянуть на, казалось бы привычные вещи. Большинство материалов, представленных в статье взяты из официальной документации и переведены в довольно свободной форме. Всех страждующих, прошу под кат.


    Для начала, давайте напишем наше первое приложение на Elm и попробуем разобраться, что же происходит. Не отходя от традиций, пусть это будет наш привет Миру.
    import Html exposing (span, text)
    import Html.Attributes exposing (class)
    
    
    main =
      span [class "welcome-message"] [text "Hello, World!"]
    


    Первые две строчки подключают модули Html и Html.Attributes, благодаря которым мы можем отображать и изменять HTML-элементы и их атрибуты на странице. Директива exposing позволяет нам использовать указанные в параметрах функции напряму, например вместо
    Html.span
    

    мы можем писать просто
    span 
    


    main это управляющая конструкция, которая управляет нашим приложением, большинству программ, написаных на Elm так или иначе будут содержать эту конструкцию.

    Строка
     span [class "welcome-message"] [text "Hello, World!"] 
    Сгенерирует простой HTML-код:
    <span class="welcome-message">Hello, World!</span>
    


    Но это все не очень интересно, ведь для генерации простого HTML-кода в одну строку нам пришлось написать целых 4 строчки на Elm, пока что не очень впечатляет, но стоит только заглянуть в основные концепции архитектуры языка и все становится на свои места.

    Вся логика программ на Elm разделена на 3 понятные и простые части, уже, так или иначе, знакомые многим в веб разработке:
    • Model(модель)
    • Update(обновление)
    • View(представление)


    Model(модель)
    Я бы охрактеризовал модель, как состояние приложения, что отличается от того, что понимается под моделью в привычном MVC. Если выразить мою мысль более подробно, то Модель в Elm будет содержать в себе все модели в понимании MVC, необходимые в данном состоянии приложению, если таковые есть. При этом Model может быть чем-то намного более простым. Например, в следующем примере, в котором мы сделаем простой счетчик, Model будет простым целым числом(Int).

    Update(обновление)
    Когда дело касается обновления состояния, в игру вступает update. Здесь все не более сложно, чем с моделью. Update это функция, которая говорит КАК нам нужно изменить состояние приложения(Model)

    View(представление)
    Преставление это то, как мы хотим отобразить состояние нашего приложения, то есть Model.

    В сухом остатке, приложение на Elm работает следующим образом:
    Мы получаем запрос из внешнего мира, Используем его для того, чтобы обновить нашу модель, решаем, как хотим отобразить результат. Elm решает, как эффективно отобразить наш HTML.

    Читая сухой текст, довольно трудно понять что к чему, поэтому, давайте рассмотрим обещаный пример создания счетчика

    module Counter where
    
    import Html exposing (..)
    import Html.Attributes exposing (style)
    import Html.Events exposing (onClick)
    import StartApp
    
    
    main =
      StartApp.start
        { model = 0
        , update = update
        , view = view
        }
    
    
    -- MODEL
    
    type alias Model = Int
    
    
    -- UPDATE
    
    type Action = Increment | Decrement
    
    update : Action -> Model -> Model
    update action model =
      case action of
        Increment -> model + 1
        Decrement -> model - 1
    
    
    -- VIEW
    
    view : Signal.Address Action -> Model -> Html
    view address model =
      div []
        [ button [ onClick address Decrement ] [ text "-" ]
        , div [ countStyle ] [ text (toString model) ]
        , button [ onClick address Increment ] [ text "+" ]
        ]
    
    
    countStyle : Attribute
    countStyle =
      style
        [ ("font-size", "20px")
        , ("font-family", "monospace")
        , ("display", "inline-block")
        , ("width", "50px")
        , ("text-align", "center")
        ]
    


    В этом примере добавилась довольно важная концепция — Action(действие). Действия позволяют нам правильно реагировать на запросы полученные из внешнего мира. В данном примере мы определили два типа действий — Increment и Decrement. И, в зависимости от полученного действия принимаем решение, как изменить нашу модель.

    Кстати, разработчики предусмотрели онлайн-компилятор, для того, чтобы можно было запустить один из множества доступных примеров, или попробовать написать что-то самостоятельно. Попробуйте запустить этот пример и посмотреть, что получится!

    Можно еще долго рассказывать о базовых концепциях данного языка, но я думаю, что те, кому изложенный материал показался хоть чуточку интересным, сами зайдут на официальный сайт и посмотрят все, что называется своими глазами. А еще, я призываю тех, кого не заинтересовало то, что я написал, или не понравился мой стиль изложения, зайти и все же посмотреть на Elm своими глазами. В заключение, я хочу добавить пример кода с официального сайта, который генерирует игру в пинг-понг в браузере, по-моему, изящность и простота этого языка, заслуживают внимания со стороны сообщества elm-lang.org/examples/pong
    Поделиться публикацией

    Похожие публикации

    Комментарии 22

      +26
      «Меня сразу вдохновила та простата» — исправьте. Думал в личку написать, но пусть уж другие тоже поржут над опечаткой. :)
        +7
        Спасибо. Хорошо, что я не пишу на медицинские темы.
          +1
          А может быть, наоборот, зря?
        0
        Хм, elm-compiler написал на Haskell, необычный выбор авторов надо сказать.
          +2
          Это чем же?
            +4
            Что необычного в написании компилятора Haskell-подобного языка на Haskell, одном из лучших языков для написания компиляторов?
              +1
              Не в курсе про то, что Haskell лучший язык для написания компиляторов. Мне казалось, что он больше академический, чем для практических нужд. Пожалуй пересмотрю свое мнение по поводу Haskell'а
                +3
                Мне казалось, что он больше академический, чем для практических нужд

                Это популярное заблуждение. При должном опыте можно делать очень классные практичные вещи на Haskell. Порог входа достаточно высок, но изучение Haskell однозначно изменит подход к программированию на других языках.
                  +2
                  Elm хорошее подтверждение Вашему заблуждению. И еще можно посмотреть на github реализации различных, вполне практичных вещей на Haskell. У меня часто возникает чувство: «Черт, почему я еще не пишу на Haskell»
              0
              Скажите, а в чем основное отличие Elm от PureScript?
                0
                Отличий довольно много, что понимать под ОСНОВНЫМ, я не понимаю. Можете ознакомится вот с этой статьей
                www.slant.co/topics/1515/compare/~elm_vs_purescript_vs_haste
                  0
                  Elm проще. Нет тайпклассов, соответственно нет развесистой библиотеки этих же тайпклассов. Язык заточен под одну парадигму. PureScript более универсальный например при желании можно использовать тот же jQuery.
                    0
                    Разработчики учли важность возможности использования ELM с существующими библиотеками и сделали вот это:
                    elm-lang.org/guide/interop
                      0
                      Да, общаться можно через порты, как вы себе представляете через них использовать jQuery?
                        0
                        как вы себе представляете через них использовать jQuery?

                        Jquery действительно никак, но
                        а) Нет видимых причин использовать jQuery с Elm
                        б) Если всеже возникла такая необходимость, то любой функционал можно написать на elm, благо, на нём это займет совсем немного времени, и принести пользу сообществу, опубликовав пакет.
                        в) я не вижу никакого ограничение на использование чистого JS в elm-проекте

                        Под в) я имею ввиду примерно такую конструкцию во View
                          script [type "text-javascript"] [src "myAwesomeScript.js"] 
                        
                  0
                  Как на elm реализуются компоненты (виджеты)?
                    0
                    Модули
                      0
                      Хотелось бы более конкретный пример.
                    0
                    Очень интересный язык.
                    Только меня в нем разочаловал запрет на рекурсивную зависимость сигналов.
                      0
                      Зачем вам рекурсивные сигналы?
                        0
                        Хотел демонстранцию работы схемы написать. Провода из схемы хорошо описывались бы сигналами, если бы их можно было зациклить.
                        А вообще глобальное состояние с помощью fold хранить не всегда бывает удобно, особенно если к нему нужен доступ из многих мест. В зацикленных сигналах хранить было бы проще.
                          –1
                          Мне кажется вы пытаетесь использовать инструмент не по назначению.

                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                    Самое читаемое