Поговорим о Elm.
Elm — функциональный язык программирования для frontend-разработки. Синтаксис похож на Haskell, но значительно упрощен и специализирован. Исходный код на Elm компилируется в нативный JavaScript. Скомпилированный JavaScript содержит код приложения, которое управляют поддеревом DOM.
Elm. Удобный и неловкий. Композиция
Elm. Удобный и неловкий. Json.Encoder и Json.Decoder
Elm. Удобный и неловкий. Http, Task
Основным элементом в архитектуре языка Elm является приложение. В общем случае каждое приложение содержит:
- Состояние или модель. Данные описывающее текущее состояние приложения;
- Множество допустимых сообщений. Сообщения отправляются при наступлении событий (допустим клик по кнопке) и доставляются в функцию update;
- Функцию view, которая на основании состояния генерирует новое DOM дерево;
- Функция update, которая принимает модель и сообщение, а возвращает новую модель и требуемые эффекты;
- Функция subscribe, подписка на уведомления о событиях. В ядре языка имеются подписки на таймер, WebSocket и прочее.
Типизация
Все должно быть типизировано. Как следствие статическая проверка согласованности кода. Если скомпилировалось, то должно работать. А вот будет оно работать как вы ожидаете или нет — никаких гарантий. Это значительно упрощает рефакторинг.
Модель
Модель является пользовательским типом. Пользовательские типы строятся из:
- Type Aliases для описания структур;
- Union Types для описания допустимых объединений типов;
- базовые типы Int, String и прочие.
Union Types позволяют объявлять тегированные типы. Возьмем для примера описания типа User:
type User = Anonymous | User String
Объявленный тип содержит информацию о типе пользователя и его данные, если он авторизован. Иначе пользователь анонимный.
Граница
Граница между Elm runtime и внешним окружением через декодеры. Декодер (Json.Decode) — функция, которая принимает на вход JSON и возвращает Elm тип. В процессе выполнения Json.Decode.decodeString или Json.Decode.decodeValue проверяется структура входных данных и соответствие типам.
Декодер возвращает тип Result, который содержит данные, в случае успеха, или ошибку.
Представление (view)
Представление является функций от состояния, которая возвращают информацию для генерации DOM дерева. Пример:
view : Model -> Html.Html Msg
view model =
case model.user of
Anonymous ->
Html.div [] [ Html.text “Anonymous” ]
User name ->
Html.div [] [ Html.text (“Welcome ” ++ name) ]
Для генерации DOM узлов используются функции. В боевых проектах view представляет собой композицию из функций более общего порядка. Например:
view : Model -> Html.Html Msg
view model =
case model.user of
Anonymous ->
anonymousView
User name ->
userView name
anonymousView и userView пользовательские функции, которые генерируют небольшие части интерфейса.
Мутации (update)
Все события (действия пользователя, сетевые и тп) генерируют сообщения, которые доставляются в зарегистрированную при инициализации функцию. По умолчанию, эта функция имеет имя update. Функция принимает событие и модель, а возвращает новую модель и команды. Команды выполняются в Elm runtime и также могут генерировать события.
Для примера, инкремент переменной при нажатии кнопки:
update : Model -> Msg -> (Model, Cmd Msg)
update model msg =
case msg of
OnClick ->
({model | clicked = model.clicked + 1}, Cmd.none)
Подписка (subscribe)
Подписка на события происходит при старте приложения и повторно вызывается при каждом изменении модели.
В случае возникновения события они доставляются в функцию update.
Для примера, подписка на таймер с периодом 10 секунд. При достижении 10 секунд генерируется сообщение Tick и доставляется в функцию update:
subscribe : Model -> Sub Msg
subscribe model =
Time.every 10 Tick
Источники
- http://elm-lang.org — сайт языка
- http://elm-lang.org/examples — примитивные примеры
- https://github.com/evancz/elm-todomvc — пример TODO приложения
- https://guide.elm-lang.org/install.html — официальная документация
- https://www.elm-tutorial.org/en/ — сторонний учебник языка
- https://github.com/isRuslan/awesome-elm — коллекция различных материалов о языке
- https://github.com/rtfeldman/elm-spa-example — пример среднего размера приложения