26 октября в г. Линц-ам-Райн (Германия) прошла мини-конференция HaxeUp Sessions 2019, посвященная Haxe и смежным технологиям. И самым знаменательным ее событием был, конечно же, финальный релиз Haxe 4.0.0 (на момент публикации, то есть спустя примерно неделю, вышло обновление 4.0.1). В этом материале я хотел бы представить вам перевод первого доклада конференции — отчета о работе, проделанной командой Haxe за 2019 год.   Немного об авторе доклада: Саймон работает с Haxe c 2010 года, когда он был еще студентом и писал работу, посвященную симуляции жидкостей во Flash. Реализация подобной симуляции требовала постоянных обращений к данным, описывающим состояние частиц (на каждом шаге осуществлялось более 100 запросов к массивам данных о состоянии каждой из ячеек в симуляции), при этом работа с массивами в ActionScript 3 не такая уж и быстрая. Поэтому первоначальная реализация попросту была нерабочей и требовалось найти решение для данной проблемы. В своих поисках Саймон натолкнулся на статью Николя Каннасса (создателя Haxe), посвященную недокументированным тогда опкодам Alchemy, которые не были доступны с помощью ActionScript, но Haxe позволял их использовать. Переписав симуляцию на Haxe с использованием опкодов, Саймон получил рабочую симуляцию! И так, благодаря медленным массивам в ActionScript, Саймон узнал о Haxe.  С 2011 года Саймон присоединился к разработке Haxe, он начал изучать OCaml (на котором написан компилятор) и вносить различные исправления в работу компилятора.  А с 2012 года он стал основным разработчиком компилятора. В том же году был создан Haxe Foundation (организация, основным целями которой являются развитие и поддержание экосистемы Haxe, помощь сообществу в организации конференций, консультационные услуги), и Саймон стал одним из его сооснователей.  В 2014-2015 году Саймон пригласил в Haxe Foundation Жозефину Пертозу, которая со временем стала отвечать за организацию конференций и связи с сообществом.  В 2016 году Саймон впервые выступил с докладом о Haxe, а в 2018 организовал первый HaxeUp Sessions.   Так что же произошло в мире Haxe за прошедший 2019 год? В феврале и марте вышли 2 релиз-кандидата (4.0.0-rc1 и 4.0.0-rc2)
В апреле к команде Haxe Foundation присоединились Аурел Били (в качестве интерна) и Александр Кузьменко (в качестве разработчика компилятора). В мае прошел Haxe US Summit 2019.
В июне вышел Haxe 4.0.0-rc3. А в сентябре — Haxe 4.0.0-rc4 и Haxe 4.0.0-rc5.  Haxe — это не только компилятор, но и целый набор различных инструментов, и в течение года работа над ними также постоянно велась:
Благодаря усилиям Энди Ли Haxe теперь использует Azure Pipelines вместо Travis CI и AppVeyor. Это значит, что сборка и автоматические тесты теперь выполняются гораздо быстрее.
Хью Сандерсон продолжает работу над hxcpp (библиотекой для поддержки C++ в Haxe).
Внезапно к работе над экстернами для Node.js присоединились пользователи Github terurou и takashiski.
Руди Гес работал над исправлениями и улучшениями для поддержки C# таргета.
Джордж Корни продолжает поддержку генератора HTML-экстернов.
Йенс Фишер работает над vshaxe (расширение для VS Code для работы с Haxe) и над многими другими проектами, связанными с Haxe.  И главным событием года конечно же стал долгожданный релиз Haxe 4.0.0 (а также neko 2.3.0), случайно совпавший с HaxeUp 2019 Linz :)  Основную часть доклада Саймон посвятил новым возможностям в Haxe 4.0.0 (о них вы также могли узнать из доклада Александра Кузьменко с прошедшего Haxe US Summit 2019).  Новый интерпретатор макросов eval в несколько раз быстрее старого. Саймон подробно рассказывал о нем в своем выступлении на Haxe Summit EU 2017. Но с тех пор в нем были улучшены возможности отладки кода, исправлено множество багов, переработана реализация строк.   В Haxe 4 появилась поддержка юникод для всех платформ (кроме Neko). Подробно об этом Саймон рассказывал в своем прошлогоднем выступлении. Для конечного пользователя компилятора это означает то, что выражение "Haxeは最高だぞ！".length для всех платформ всегда будет возвращать 10 (опять же, кроме Neko). Минимально поддерживается кодировка UCS-2 (для каждой платформы / языка используется нативно поддерживаемая кодировка; пытаться поддерживать везде одну и ту же кодировку было бы непрактично): Все символы, находящиеся за пределами основной многоязычной плоскости (в том числе и эмодзи), представляются в виде “суррогатных пар” — такие символы представляются двумя байтами. Например, если в Java/C#/JavaScript (то есть для строк в UTF-16 и UCS-2 кодировках) запросить длину строки, состоящей из одного эмодзи, то результатом будет “2”. Этот факт нужно принимать во внимание при работе с такими строками на данных платформах. В Haxe 4 появился новый вид итератора — “ключ-значение”:  Он работает с контейнерами типа Map (словари) и строками (с помощью класса StringTools), поддержка для массивов пока что не реализована. Также есть возможность реализовать такой итератор для пользовательских классов, для этого достаточно реализовать для них метод keyValueIterator():KeyValueIterator<K, V>. Новый мета-тэг @:using позволяет связывать статические расширения с типами по месту их объявления. В примере, приведенном на слайде ниже, перечисление MyOption связывается с MyOptionTools, таким образом мы статически расширяем данное перечисление (что в обычной ситуации невозможно) и получаем возможность вызывать метод get(), обращаясь к нему как к методу объекта.   В этом примере метод get() является встраиваемым (inline), что также позволяет компилятору дополнительно оптимизировать код: вместо вызова метода MyOptionTools.get(myOption), компилятор подставит хранимое значение, то есть 12. Если же метод не объявлен как встраиваемый, то еще одним средством оптимизации, доступным программисту, является встраивание функций по месту их вызова (call-site inlining). Для этого при вызове функции нужно дополнительно использовать ключевое слово inline:  Благодаря работе Даниила Коростелева в Haxe появилась возможность генерации ES6-классов для JavaScript. Все что нужно для этого сделать — просто добавить флаг компиляции -D js-es=6.  В настоящий момент компилятор генерирует один js-файл для всего проекта (возможно в будущем появится возможность генерации отдельных js-файлов для каждого из классов, но пока что это можно сделать только с помощью дополнительных инструментов).   Для абстрактных перечислений теперь автоматически генерируются значения.  В Haxe 3 было необходимо вручную задавать значения для каждого конструктора. В Haxe 4 абстрактные перечисления, созданные поверх Int, ведут себя по тем же правилам, что и в C. Аналогично ведут себя абстрактные перечисления, созданные поверх строк — для них сгенерированные значения будут совпадать с именами конструкторов.  Следует упомянуть также некоторые улучшения в синтаксисе:  Новый синтаксис для описания типов функций (function type syntax) является более логичным: использование скобок вокруг типов аргументов функции визуально легче воспринимается. Кроме того, новый синтаксис позволяет определять имена аргументов, что можно использовать как часть документации к коду (хотя никак не влияет на саму типизацию).  Старый синтаксис при этом продолжает поддерживаться и не объявлен устаревшим, т.к. в противном случае это потребовало бы слишком много изменений в существующем коде (сам Саймон постоянно ловит себя на том, что по привычке продолжает использовать старый синтаксис). В Haxe 4 наконец-то появились стрелочные функции (или лямбда-выражения)!  Особенностями стрелочных функций в Haxe являются: В общем, синтаксис стрелочных функций очень похож на используемый в Java 8 (хотя и работает несколько иначе). И раз уж мы упомянули Java, то следует сказать о том, что в Haxe 4 появилась возможность генерации JVM-байткода напрямую. Для этого при компиляции проекта под Java достаточно добавить флаг -D jvm.  Генерация JVM-байткода означает, что необходимость использования Java-компилятора отпадает, при этом процесс компиляции осуществляется значительно быстрее.  Пока что JVM-таргет имеет статус экспериментального по следующим причинам:  Общее сравнение генерации байткода напрямую (genjvm) и компиляции Haxe в Java-код, который затем компилируется в байткод (genjava): Общие советы при работе с Java в Haxe: Избежать использования Null<T> может помочь новая фича Haxe 4 — Null-безопасность (Null safety). Александр Кузьменко подробно о ней рассказал на прошлогоднем HaxeUp.   В примере на слайде выше для статического метода safe() включен Strict-режим проверок на Null-безопасность, при этом данный метод имеет необязательный параметр arg, который может иметь нулевое значение. Для того, чтобы данная функция успешно скомпилировалась, программисту потребуется добавить проверку значения аргумента arg (в противном случае компилятор выдаст сообщение о невозможности вызвать метод charAt() у потенциально нулевого объекта).  Null-безопасность можно настраивать как на уровне пакетов (с помощью макроса), так и типов и отдельных полей объектов (с помощью мета-тэга @:nullSafety). Режимы, в которых работают проверки на Null-безопасность, следующий: Strict, Loose и Off. Глобально эти проверки отключены (Off-режим). При их включении по-умолчанию используется Loose-режим (если явно не указать режим). Ключевым отличием между Loose и Strict режимами является то, что Loose-режим игнорирует возможность изменения значений между операциями обращений к этим значениям. В примере на слайде ниже мы видим, что для переменной x добавлена проверка на null. Однако в Strict-режиме данный код не скомпилируется, т.к. перед непосредственной работой с переменной x вызывается метод sideEffect(), который потенциально может обнулить значение этой переменной, таким образом потребуется добавить еще одну проверку или скопировать значение переменной в локальную переменную, с которой и будем работать в дальнейшем.  В Haxe 4 появилось новое ключевое слово final, которое в зависимости от контекста имеет различный смысл:  Теоретически компилятор, встретив ключевое слово final, может попытаться оптимизировать код, предполагая, что значение данного поля не меняется. Но пока что такая возможность только рассматривается и в компиляторе не реализована.  И немного о будущем Haxe: Программист