10 пре­иму­ществ Elm: пе­рехо­дим на функ­ци­ональ­ное прог­рамми­рова­ние во Fron­tend'e

1 ноября 2019

Elm как функциональный язык для фронтенд-разработки широко известен в узких кругах. Его синтаксис напоминает упрощенный и специализированный Haskell для пользовательских web-интерфейсов. У Elm есть ряд очевидных преимуществ по сравнению с React.js, однако массовой популярности у фронтенд-разработчиков он не снискал. Почему? Разберемся вместе с Frontend-командой DSR Corporation.


Использование языка Elm даёт преимущества как конечному пользователю, так и Fronted-разработчику. Первый получает в большинстве случаев увеличенную скорость загрузки страниц и отсутствие ошибок. Второй – внятные предупреждения компилятора, быструю компиляцию и понятные инструкции для перехода на новую версию пакетов. В итоге от использования Elm выигрывает практически любая Frontend-команда.

Создатель Elm, Эван Чаплицкий не занимается маркетингом своего языка. Будучи невероятно талантливым программистом, он еще и прекрасно понимает, в каком направлении нужно развивать свое детище, а именно – сделать Elm самым надежным языком программирования для разработки пользовательских интерфейсов. Мало кто тратит ресурсы на его продвижение в отличие, скажем, от библиотеки React.js, который Facebook активно поддерживает, устраивает конференции и всячески рекламирует. Технически Elm не уступает React.js, а в некоторых аспектах даже превосходит. Правда, мало кто об этом знает.

Основные преимущества Elm

Легко научиться. Множество ресурсов с гайдами, советами, FAQ, книгами и доброжелательное комьюнити разработчиков. Легендарный программист Кевин Янк ведет подкасты по ELM. Огромный корпус обучающих материалов доступен бесплатно.

Общая стоимость проекта за весь жизненный цикл значительно ниже. По сравнению с другими фреймворками, Elm делает поддержку проекта (львиная доля жизненного цикла приложения) заметно проще за счет предупреждений компилятора – они не дают делать изменения, которые ваше приложение не сумеет скомпилировать.

Интероперабельность с JavaScript посредством портов. Когда вы начинаете писать приложения (и пакеты) на Elm, возникает острое желание как можно реже обращаться к суматошному миру JavaScript. Однако, на реальных проектах не всегда оправдано переписывать уже готовые JS-решения на чистом Elm. Иногда это попросту невозможно.

В Elm есть отличный механизм интеграции кода на JavaScript при необходимости – порты. Они подходят не для каждой задачи, но в Elm есть и другие инструменты интероперабильности.

Нет ошибок времени выполнения. Полное отсутствие сценария, когда программа на Elm выдает ошибку, ломающую UI. Опытные Frontend-разработчики оценят!

Сопровождаемость. Если код не компилируется, то он и не будет выполняться. Встроенная гарантия безопасности. Сюда же запишем Enforced Semantic Versioning (принудительное семантическое обновление версий). Если что-то меняется в пакете, от которого зависит проект, автор этой взаимозависимости вынужден обновить номер версии, поэтому Frontend-разработчик получит предупреждение, что пакет больше не совместим с приложением. Используя Elm невозможно сломать рабочую среду.

Кто использует Elm? Из крупных брендов — frontend-команда IBM, причем отзывы положительные. «ELM действительно пуленепробиваемый, и это не пустой рекламный слоган». Стоит также назвать Rakuten японский аналог Amazon и владелец популярного мессенджера Viber. Больше компаний тут.

Производительность. ELM Virtual Dom легковеснее, чем у React.js, размер бандла, как правило, меньше, так что рендеринг первого отображения в любом браузере на любом устройстве на вашем Frontend-проекте будет быстрее.

Image

Экосистема пакетов Open Source. бесплатный код, на который Frontend-разработчики уже потратили миллионы часов. Можете использовать его в своем проекте совершенно бесплатно, а semantic versioning гарантирует, что чужой код ничего не сломает.

Progressive Web Apps. С ELM легко! Пример PWA с открытым исходным кодом.

Рендеринг на стороне сервера (Server Side Rendering). Официально ELM не поддерживает SSR, но грамотные Frontend-разработчики умеют: примеры раз, два и три.

Перейти на Elm будет легко любому Frontend-разработчику

Нужно ли немедленно отказываться от привычных инструментов и бежать в «пуленепробиваемый» мир Elm? Ни в коем случае. Стоит как минимум обратить внимание на этот изящный и мощный функциональный язык для Frontend-разработки. Почитать «гайды», посмотреть примеры кода, попробовать сделать на Elm что-то элементарное. И только потом, уже на базе собственного опыта и в реальных условиях ваших проектов, принимать взвешенное решение. Сам переход на Elm будет безболезненным и легким, даже для начинающих.

Большинство Frontend-разработчиков знают, как устроен Redux. Интересно, что эта библиотека JavaScript была создана на базе архитектуры Elm. Очередной пример проявления тренда «усталости от JavaScript», когда в мир JS все чаще и чаще используются альтернативные решения. Поскольку Elm стал «отцом» Redux, требует иммутабельности, декларативного программирования и имеет собственную имплементацию виртуального DOM, то он будет достаточно близок frontend-разработчикам, предпочитающим экосистему React.

Приведем несколько примеров кода на Elm, чтобы показать его элегантность, читаемость и простоту.

Цепочка функций

В отличие от JavaScript, где каждую функцию приходится оборачивать, в Elm есть специальный пайп-оператор, позволяющий развернуть цепочку функций в более читабельном для программиста виде. Особенность Elm как функционального языка.

1  -- Piping: Chaining functions
2 
3  foo =
4    Html.text (String.fromInt (add 5 (multiply 10 (divide 30 10))))
5
6  -- x |> f = f x
7  baz =
8    divide 30 10
9        |> multiply 10
10       |> add 5
11       |> String.fromInt
12       |> Html.text

Композиция функций

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

1  -- Function composition
2
3  -- String.words : String -> List String
4  -- List.length : List a -> Int
5  -- (>>) : (a -> b) -> (b -> c) -> a -> c
6  wordCount = String.words >> List.length
7  -- wordCount : String -> Int
8  result = wordCount "use Elm and prosper"

Работающее приложение на Elm

Счетчик уменьшения/увеличения значений с целыми числами, пример кода кнопок

Любое приложение, написанное на Elm, состоит из модулей (как и в JS). Каждый модуль состоит из трех частей.

  1. Model. Состояние приложения.
  2. Update. Способ обновления состояния.
  3. View. Способ отображения состояния.
1
2
3 import Browser
4 import Html exposing (Html, button, div, text)
5 import Html.Events exposing (onClick)
6
7
8
9  -- MAIN
10
11
12 main =
13   Browser.sandbox { init = init, update = update, view = view },
14
15
16
17 -- MODEL
18
19
20 type alias Model = Int
21
22
23 init : Model
24 init =
25    0
26
27
28
29 -- UPDATE
30
31
32 type Msg
33   = Increment
34   | Decrement
35
36
37 update : Msg -> Model -> Model
38 update msg model =
39   case msg of
40      Increment ->
41        model + 1
42
43      Decrement ->
44       model - 1
45
46
47
48   -- VIEW
49
50
51 view : Model -> Html Msg
52 view model =
53    div []
54        [ button [ onClick Decrement ] [ text "-" ]
55        , div [] [ text (String.fromInt model) ]
56        , button [ onClick Increment ] [ text "+" ]
57        ]

На примере выше на 20-й строке используется type alias и объявляется, что в модели у нас будет хранится только Int. На 23-25 строках используется функция init, чтобы инициализировать наше приложение с определенным дефолтным значением.

На строке 51 объявление функции view, позволяющей генерировать HTML. View всегда принимает модель, благодаря чему Frontend-разработчик в Elm может оперировать состоянием приложения.

Смотрим на строку 54, где мы видим вызов функции button, которой в качестве первого параметра передается массив атрибутов, где фигурирует обработчик событий onclick. В качестве второго параметра передается массив дочерних элементов. В данном примере фигурирует функция text, генерирующая текстовую ноду. Событие onclick, предполагающее выполнение какого-либо действия. В нашем примере – уменьшение значения счетчика. Функция text возвращает string, строковый тип.

Приложение Elm запускается с отображением на экране первоначального значения. Затем работает в следующем бесконечном цикле:

  1. Ждет клика пользователя по кнопке.
  2. Отсылает сообщение в update
  3. Производит новую модель (model)
  4. Вызывает view, чтобы сгенерировать новый HTML
  5. Показывает новый HTML в браузере.
  6. Переходит к первому пункту цикла.

Это суть архитектуры Elm.

Попробуйте модифицировать приложение по этой ссылке. К примеру, добавить вариант Reset к типу Msg.

Elm как функциональный язык разработки интерфейсов для фронтенда может стать вашим любимым инструментом, если учесть все его особенности и преимущества. Будущее – за функциональным программированием, но об этом поговорим в следующей статье. А пока не упускайте шанс опередить конкурентов.

Хотите попробовать свои силы на крупных и интересных проектах по Frontend-разработке для таких известных брендов, как Amazon и Netflix? Присоединяйтесь к дружной и профессиональной команде web-разработчиков DSR Corporation.