Elm изменил мое представление о непопулярных языках
Перевод статьи Alexander Campbell: Elm changed my mind about unpopular languages
Вы когда-нибудь обращались к программному обеспечению так, чтобы это выходило за рамки обыденного? Возможно, вы пытались сделать программное обеспечение для своего графического калькулятора Fx-9860GX и понимали, что вы были одним из тех пяти человек, которые когда-либо пытались это сделать вообще, при том, что документации не было. Опыт отстойный. Или возможно вы относитесь к такому типу людей, которые получают удовольствие посредством мудреных ошибок и полного отсутствия документации (к коим иногда отношусь и я), но я решил, что в профессиональной разработке программного обеспечения, где важен вопрос его поставки на рынок, я буду придерживаться только самых широко используемых инструментов.
Для себя я сделал твердое и решительное правило: если я найду две технологии, которые могут решить какую-то проблему, то я предпочту ту, которой пользуется больше людей. К слову, я не хотел бы включать в проект неясный API для работы с графикой, а затем искать в коде, чтобы никто не вызывал функцию set_color()
после функции resize_window()
(да, изменение размеров окна это тяжело), ведь последовательное выполнение этих двух функций является причиной ошибки сегментации памяти. Я не хочу быть парнем, который найдет ошибку в компиляторе. Мне просто нужно разработать программный продукт.
Частично мое сомнение по поводу использования новых платформ связано с двухлетним опытом написание на языке Go, до того как произошла история с управлением зависимостей. Сообщество было разбито на множеством болезненных или посредственных решений: gopkg.in, godep, glide, gb и так далее. Потребовалось годы, чтобы разработчики «успокоились» (да, я легко бросаюсь этим словом) и остановилось на godep, а ведь это было не так недавно, когда сообщество Go его полностью приняло, это был относительно безболезненный опыт. И недавно я узнал, что разработчики языка Go могут представить официальное решение: golang/dep.
Со своим новым правилом я чувствовал себя уверенным в выборе своего стека. Когда я искал инструменты для создания веб-приложения, то рассматривал только массово используемые и популярные инструменты, такие как Bootstrap и jQuery. У каждой из этих библиотек несметное число пользователей каждый месяц, поэтому все возможные ошибки проработаны, не так ли? Даже если, у меня возникнет проблема, уверен, кто-то уже получал ответ на нее на StackOverflow. Все как по маслу. И вуаля, все уже работает. Вы можете пройтись по всему жизненному циклу веб-приложения, и вы редко столкнетесь с ситуацией, когда вы не можете найти решение проблемы в течение 5 секунд в сети. Кто-то уже исправил это. Моя стратегия была безупречной.
Но когда я присоединился к Real Kinetic, я узнал, что мы разрабатываем клиентское веб-приложение на Elm. Elm? Серьезно? Это же экспериментальный язык, созданный для Haskell-снобов, которые не могут справиться с обычным языком для синих воротничков, таким как JavaScript? Я представлял поклонников языка Elm так, словно вокруг меня стояли хипстеры, говорящие о том, что побочные эффекты в веб-приложениях — это же 2008 год, бро. Определенно, я не представлял их как людей, которые поставляют приложения на рынок программного обеспечения. На мой взгляд, Elm не соответствовал производственной среде.
Поэтому в течение первых нескольких недель я был настроен скептически. Но затем, когда я в третий раз изучал руководство по архитектуре Elm, наконец, что-то щелкнуло у меня в голове. Я понял. Вот это да! Да это же намного лучше, чем JavaScript. Я могу посмотреть на код и с уверенностью предсказывать его поведение, его пограничные случаи и все остальное.
Во-первых, Elm имеет естественную для чистого функционального языка предсказуемость; когда вы пишете Elm, компилятор заставляет вас обдумывать каждый случай. Рассмотрим следующий пример: для своего друга вы пишете некоторое приложение для учета книг в библиотеке. Он хочет возможность получать отчет, в котором бы отображалось, сколько книг находится в каталоге, дата издания самой ранней и самой поздней книги в библиотеке и количество уникальных авторов.
Я могу более подробно рассмотреть этот код. Например, вот этот фрагмент:
Здесь мы используем две библиотечные функции: List.maximum
и Maybe.withDefault
. Назначение и использовании функции List.maximum
очевидны, также его сигнатура типа является показательной.
В данном случае, поскольку наш список имеет тип «List Int», функция возвращает «Maybe Int». Концепция использования Maybe
знакома людям пришедшим из Haskell (Maybe), из Rust (Option) или из Java (Optional). Maybe
— это контейнер с нулевым (Nothing) или одним (Just x) элементом. Мы можем использовать функцию Maybe.withDefault
для «распаковки» значения Maybe
, заменяя на значение по умолчанию, если контейнер Maybe
пуст.
Таким образом, этот фрагмент кода извлекает максимальное значение в списке copyrightYears
, если оно существует. Если же нет, мы просто возвращаем ноль. Elm требует, чтобы вы продумали все пограничные случаи. Вы должны рассмотреть и указать, что произойдет в каждом случае. Именно по этой причине Elm может реально обещать отсутствие исключений во времени выполнения.
Вторая причина, почему Elm лучше, чем JavaScript — это то, что Elm естественно подходит для работы с DOM. Это настолько естественное чувство, что кажется, что HTML был разработан специально для Elm, но не наоборот. Отчасти причина заключается в том, что Elm использует концепцию виртуального DOM, с которой вы можете быть знакомы, если сталкивались с React (именно виртуальный DOM является причиной, почему представление может быть автоматически обновлено с помощью измененной модели приложения. Примечание редактора : В данном случае кажется, что автор заблуждается. Виртуальный DOM нужен для снижения стоимости таких обновлений). Здесь показано то, как мы можем отобразить тип LibraryReport
в HTML:
Обратите внимание на то, как мы составили функцию renderRow
включающую viewReport
. Отображаемый результат:
Разработка с Elm — это сплошная череда приятных сюрпризов: элегантный интерфейс командной строки, полезный при разработке компилятор, интуитивно понятный отладчик.
К числу этих неожиданностей относятся (спойлеры):
- Элегантный интерфейс командной строки
elm-package
иelm-make
. - Автоматическое форматирование кода с помощью
elm-format
(похоже на gofmt). - Автоматическое принудительное версионирование пакетов по semver.
- Elm-Reactor, отличный способ начать разрабатывать новые проекты.
- Режим отладки в Elm со встроенным time-travel.
Самыми большими минусами Elm являются то, что:
- Это функциональный язык, и поэтому кривая обучения круче для тех программистов, кто пришел из императивных языков.
- Вероятно, вы не сможете использовать его на стороне сервера (язык не такой универсальный, как JavaScript).
- В нем отсутствуют некоторые высокоуровневые возможности других функциональных языков, таких как в Haskell.
- Строгая семантика зависимостей накладывает ограничение на разработчиков библиотек для Elm по немедленному их обновлению, когда зависимости изменились, чтобы не блокировать последующие обновления.
Вам кажется, что здесь чего-то не хватает? Даже несмотря на то, что Elm — небольшой язык с небольшим сообществом, это никак не влияет заметным образом на опыт разработки на Elm.
Теперь я решительно отдаю предпочтение Elm для любого нового клиентского веб-приложения. Elm обладает и другими преимуществами, которые лежат на поверхности, такими как высокая производительность, достойная поддержка библиотек, а также продуманный дизайн взаимодействия с JavaScript, но для меня преимущество в Elm — это то, что он дает мне уверенность в моем коде.
Слушайте наш подкаст в iTunes и SoundCloud, читайте нас на Medium, контрибьютьте на GitHub, общайтесь в группе Telegram, следите в Twitter и канале Telegram, рекомендуйте в VK и Facebook.