В своем докладе Юрай в легкой форме рассказал о том, что же такое Haxe, какова его история и какое применение он нашел в Docler Holding. По выражению Marcelo Serpa данное выступление можно назвать попыткой объяснить Haxe пятилетнему ребенку. По-моему это очень удачное сравнение :)
Видео-версия доклада доступна на сайте Haxe.
Что же, черт побери, такое Haxe?
Это сложный вопрос. Haxe это не просто язык программирования, это своего рода единорог, уникальное существо. Звучит, конечно, слишком хорошо, чтобы быть правдой.
Но это язык, который может работать где-угодно. Его можно скомпилировать в JavaScript, C++, PHP, Python, Lua, C, C#, Java, HashLink, Neko VM (эти две виртуальные машины предназначены в основном для использования при разработке под Haxe) и Flash (который скоро уйдет в небытие).
А также он может всё: объектно-ориентированное программирование, функциональное программирование, языково-ориентированное программирование, аспектно-ориентированное программирование. В его системе типов столько средств, что мало кто сможет объяснить их все.
И самая любимая для Юрая вещь в Haxe - это макросы - система метапрограммирования (исполняемая во время компиляции программы).
Поэтому когда вы пытаетесь объяснить кому-то, что же такое Haxe, то вы становитесь похожим на этого персонажа:
Что ж, давайте разбираться дальше…
Первый вопрос, который может прийти в голову после такого описания Haxe: если он настолько хорош, то почему я не слышал о нем, почему никто им не пользуется?
Это хороший вопрос.
Для начала давайте посмотрим, кто же им пользуется:
Laerdal использует Haxe для создания приложений для обучения медицинского персонала (об этом был небольшой доклад на конференции в Амстердаме). В их приложениях отрабатываются реальные ситуации, возникающие в практике врачей.
TiVo - одна из первых крупных компаний, начавших использовать Haxe. Перевели миллион строк ActionScript-кода на Haxe, и в результате улучшили скорость работы своих приложений.
Разработчики игр, конечно же, составляют существенную часть Haxe-сообщества:
FlowPlay - еще одни безумцы, решившие портировать более миллиона строк ActionScript-кода на Haxe.
InnoGames - крупная немецкая компания, занимающаяся разработкой браузерных и мобильных онлайн-игр. Также используют Haxe для портирования игр на Flash, однако, построенный ими процесс сборки приложения позволил сохранить исходный ActionScript-код, который автоматически преобразуется в Haxe и затем компилируется в JavaScript. Об этом процессе также был доклад на Haxe Summit 2017 в Амстердаме.
Motion Twin - компания, в которой родился Haxe. Созданная ими игра Dead Cells (написана, конечно же, на Haxe) получила награду как лучшая action-игра на The Game Awards 2018.
Shiro Games - компания Nicolas Cannasse - создателя Haxe.
Proletariat Games - компания, использующая совместно Haxe и Unreal Engine. Такое сочетание технологий позволило им привнести в Unreal функцию “live code reloading” (возможность редактировать код программы и видеть изменения тут же в запущенном клиенте без полной перекомпиляции и перезапуска). И это крутая штука, т.к. если вы работаете с Unreal, то вы либо пишете код на C++, и тогда должны смириться с длительным временем компиляции проекта и с не очень информативными сообщениями об ошибках компиляции, либо вы используете блюпринты, которые хотя и удобны для непрограммистов, но если вам нужен по-настоящему быстрый код, то они вам с этим не помогут.
Этот список игровых разработчиков можно продолжать и продолжать, но я ограничусь только перечисленными.
Хотя нет, есть еще один известный разработчик:
Ок, Haxe все-таки используется, но откуда он появился, почему его применение сильно ограничено, что в итоге с ним произойдет?
Иногда для понимания вещей бывает полезно вернуться к их истокам. Давайте и мы вернемся в прошлое:
15 лет назад (вечность по меркам интернета) было довольно дикое время:
Тогда актуальными были:
А впереди нас ждали:
Это были темные века!
И примерно в это время появилась идея RIA - Rich Internet Applications:
В общем случае RIA включали в себя:
И самое крутое в этом было то, что RIA по функциям можно было сравнить с полноценными настольными приложениями, но работали они на всех платформах, так как FlashPlayer работал на 99% компьютеров. Для тех времен это было великолепно.
Но разработка такого приложения означала, что вам придется столкнуться с такими проблемами как:
Примерно в это время Motion Twin начали работать над ActionScriptMetaLanguage, который представлял собой ActionScript с типами (да, тогда в ActionScript не было типов). Затем этот проект разделился на два отдельных: MTASC - первый компилятор ActionScript 2 с открытым исходным кодом (в ActionScript 2 появилась-таки поддержка типов) и MotionType - язык, который использовался в Motion Twin. MotionType мог компилироваться под NekoVM для работы на серверах, его основной идеей была возможность использования одного кода и на сервере и на клиенте.
И в 2006 году из этого родился haXe - один язык, который мог бы работать и на сервере (NekoVM) и на клиенте (DHTML и Flash) и позволял бы легко передавать данные между платформами (например, из Neko в JavaScript).
Это то, что в 2010 году получило название Full Stack Development!
И увидев это, вы бы предположили, что все бы побежали использовать haXe в работе:
Но все пошло не так:
Большинство решило остаться в каменном веке.
Одна из причин, почему так произошло - это то, что людям тяжело изменять своим привычкам.
Но, конечно же, это не единственная причина непопулярности Haxe:
Но есть и хорошие новости, кое-что изменилось:
И, наверное, это даже неплохо.
Но вы можете задаться вопросом: в 2019 году уже есть язык, который работает везде - JavaScript, какой тогда смысл использовать Haxe?
И по-моему ответ на этот вопрос состоит из двух частей:
В качестве проекта на Haxe, демонстрирующего возможности Haxe, можно привести HaxeUI. С ней один и тот же код для пользовательского интерфейса можно скомпилировать практически под любую платформу, кроме iOS (но и эта платформа может быть охвачена).
Один и тот же код, скомпилированный под Linux (Ubuntu), MacOS и Windows:
Также проект с HaxeUI можно скомпилировать и под Android:
И на выходе вы получите нативный Java-код, а не JavaScript, который бы выполнялся в отдельной среде и взаимодействовал с системой с помощью дополнительной абстракции, как в случае с React Native.
Есть даже возможность собрать проект с использованием библиотеки PDCurses:
Так что Haxe действительно работает везде.
Haxe также используется в Docler. И если говорить начистоту, то поначалу работа с ним не очень задалась. Но давайте я расскажу об этом поподробнее и о том, как в итоге мы решили наши проблемы.
У нас был критически важный продукт, который использовал Flash. В какой-то момент было решено переписать его на ActionScript 3. И мы словили синдром второй системы - все хотели улучшить продукт, добавить в него новых функций. Но нам повезло, так как Flash отлично справился и с этим чрезмерным усложнением системы.
Затем Apple объявила смерть Flash, что повлекло за собой решение портировать продукт на Haxe (с использованием as3hx).
И результат портирования оказался совсем не так хорош, как мы ожидали. Спустя примерно год работы мы получили один большой JavaScript файл, код работал ужасно медленно и содержал множество ошибок.
Последовавшая реакция в компании была примерно следующая:
Все хотели избавиться от использования Haxe. И это желание легко понять - после года тяжелой работы мы получили неработающее приложение со множеством проблем, которые было непонятно как решать. Например, видеостриминг - во Flash он просто работает, а как заставить его (стриминг видео) работать во всех браузерах без Flash никто не знал.
Мы совершили множество ошибок:
Где-то в это время Юрай пришел работать в Docler. В ходе обсуждений сложившейся ситуации был составлен список вещей, которые могли бы помочь решить имеющиеся проблемы:
План действий был следующий:
То есть нам нужна была связка React и MobX?
Когда вы только приступаете к разработке нового приложения, то начать использовать React и MobX довольно просто. Однако у нас на руках была огромная кодовая база со своей логикой поведения, и использование React и MobX, которые навязывают свое поведение, нам не подходило.
Реализация принятого плана и требуемых технических решений:
И, конечно же, я ожидал, что команда сразу подхватит мои разработки:
Но многие все-таки предпочли работать по-старому (по многим причинам):
Но потом наша команда постепенно начала использовать эти наработки:
Хотя это был непростой процесс.
На графике представлена динамика этого процесса с августа 2017 года по настоящее время. Размер скомпилированного и минифицированного приложения уменьшился с 4 Мб до примерно 1,2 Мб.
Каждый скачок вверх на графике означает добавление новых фич, а каждое падение - наведение порядка в коде.
А красная линия на графике показывает снижение числа строчек кода в проекте - практически в 2 раза. И это при том, что новые фичи продолжают добавляться в проект. Что довольно круто.
Но наша компания все же переходит на использование React. И мне пришлось написать специальный рендер для Coconut, который связывает компоненты Coconut и React и позволяет использовать функции React в Coconut.
И он работает, по крайней мере наш QA-отдел говорит так.
Этот переход на React не потребовал больших изменений в проекте - всего около 400 строк кода (из 55 тысяч строк всего проекта).
Релиз планируется примерно в марте.
И наш опыт можно рассматривать как демонстрацию возможностей Haxe.
И еще хотелось бы кратко коснуться такой сильной стороны Haxe - это то, что можно “научить” компилятор понимать новые концепции, и пользуясь этими концепциями упростить такие вещи, как, например, наш переход на React, или переход с React на Vue и т.д.
Простой пример такого “обучения” компилятора - библиотека, которая встраивает CSS-семантику в Haxe. При этом для работы автодополнения никаких изменений в работу IDE не нужно делать: мы “учим” компилятор, компилятор предоставляет функции автодополнения для IDE, компилятор также валидирует новый код. Например, если вы сделаете опечатку и вместо элемента form запросите from, то компилятор выдаст ошибку о том, что from - не является известным тегом:
И если сравнивать Haxe c TypeScript, то в некоторых случаях система типов TypeScript более выразительная, но компилятор TypeScript нельзя научить таким новым трюкам, заставить его контролировать формат введенной строки.
И это не все, на что способен компилятор Haxe, и мы сможем “научить” его новым вещам и, таким образом, упростить себе жизнь в дальнейшем.
В Docler любят Haxe и хотят разделить свою любовь со всеми. Именно поэтому было организовано это мероприятие, поэтому Docler стал стратегическим партнером Haxe Foundation и поэтому в 2017 году был организован Haxe Summit в Амстердаме.
Партнерство Haxe и Docler взаимовыгодное, и я надеюсь, что работа с Haxe принесет выгоду и вам!