Haxe Autumn Status Report

On October 26, Linz am Rhein (Germany) hosted the HaxeUp Sessions 2019 mini-conference dedicated to Haxe and related technologies. And its most significant event was, of course, the final release of Haxe 4.0.0 (at the time of publication, that is, after about a week, update 4.0.1 was released ). In this article, I would like to present you a translation of the first report of the conference - a report on the work done by the Haxe team for 2019.







image







A little about the author of the report:







Simon has been working with Haxe since 2010, when he was still a student and wrote a work on fluid simulations in Flash. The implementation of such a simulation required constant access to data describing the state of the particles (at each step more than 100 queries were made to the data arrays about the state of each cell in the simulation), while working with arrays in ActionScript 3 is not so fast. Therefore, the initial implementation was simply inoperative and needed to find a solution to this problem. In his search, Simon came across an article by Nicolas Kannass (creator of Haxe) on the then undocumented Alchemy opcodes that were not available using ActionScript, but Haxe allowed them to be used. By rewriting the simulation on Haxe using the opcodes, Simon got a working simulation! And so, thanks to slow arrays in ActionScript, Simon learned about Haxe.







Since 2011, Simon joined the development of Haxe, he began to study OCaml (which is written on the compiler) and make various corrections to the compiler.







And since 2012, he became the main compiler developer. In the same year, the Haxe Foundation was created (an organization whose main goals are to develop and maintain the Haxe ecosystem, help the community organize conferences, and provide consulting services), and Simon became one of its co-founders.







image







In 2014-2015, Simon invited Josephine Pertosa to the Haxe Foundation, which over time became responsible for organizing conferences and community relations.







In 2016, Simon made his first presentation on Haxe , and in 2018 organized the first HaxeUp Sessions .







image







So what happened in the Haxe world over the past 2019?







In February and March, 2 release candidates came out (4.0.0-rc1 and 4.0.0-rc2)

In April, Aurel Bili (as an intern) and Alexander Kuzmenko (as a compiler developer) joined the Haxe Foundation team.







In May, the Haxe US Summit 2019 was held .

In June, Haxe 4.0.0-rc3 was released. And in September - Haxe 4.0.0-rc4 and Haxe 4.0.0-rc5.







image







Haxe is not only a compiler, but also a whole set of various tools, and throughout the year work on them was also constantly conducted:

Thanks to the efforts of Andy Lee, Haxe now uses Azure Pipelines instead of Travis CI and AppVeyor. This means that assembly and automated tests are now much faster.

Hugh Sanderson continues to work on hxcpp (a library for supporting C ++ in Haxe).

Suddenly, users of Github terurou and takashiski joined the work on externs for Node.js.

Rudy Ges worked on fixes and improvements to support the C # target.

George Corney continues to support the HTML extern generator.

Jens Fisher is working on vshaxe (an extension for VS Code for working with Haxe) and on many other Haxe related projects.







image







And the main event of the year, of course, was the long-awaited release of Haxe 4.0.0 (as well as neko 2.3.0), which accidentally coincided with the HaxeUp 2019 Linz :)







image







Simon devoted the bulk of the report to new features in Haxe 4.0.0 (you can also learn about them from the report of Alexander Kuzmenko from the last Haxe US Summit 2019).







image







The new eval macro interpreter is several times faster than the old. Simon talked about him in detail in his speech at the Haxe Summit EU 2017 . But since then it has improved the debugging capabilities of the code, fixed many bugs, redesigned the implementation of strings.







image







Haxe 4 introduces Unicode support for all platforms (except Neko). Simon described this in detail in his last year’s speech . For the end user of the compiler, this means that the expression "Haxeは最高だぞ!".length



for all platforms will always return 10



(again, except for Neko).







The UCS-2 encoding is minimally supported (a natively supported encoding is used for each platform / language; trying to support the same encoding everywhere would be impractical):









All characters that are outside the main multilingual plane (including emoji) are represented as “surrogate pairs” - such characters are represented by two bytes. For example, if in Java / C # / JavaScript (that is, for strings in UTF-16 and UCS-2 encodings) to request the length of a string consisting of one emoji, the result will be “2”. This fact must be taken into account when working with such strings on these platforms.







Haxe 4 introduces a new kind of iterator - key-value:







image







It works with Map



containers (dictionaries) and strings (using the StringTools class), support for arrays has not yet been implemented. It is also possible to implement such an iterator for custom classes, for this it is enough to implement the keyValueIterator():KeyValueIterator<K, V>



method for them keyValueIterator():KeyValueIterator<K, V>



.







The new meta tag @:using



allows you to associate static extensions with types at the place of their declaration.







In the example on the slide below, the MyOption



enumeration MyOption



associated with MyOptionTools



, so we statically expand this enumeration (which is impossible in the usual situation) and get the opportunity to call the get()



method, referring to it as an object method.







image







In this example, the get()



method is inline, which also allows the compiler to further optimize the code: instead of calling the MyOptionTools.get(myOption)



method, the compiler will substitute the stored value, i.e. 12



.







If the method is not declared as embeddable, then another optimization tool available to the programmer is to embed functions at the place of their call (call-site inlining). To do this, when calling the function, you must additionally use the inline



:







image







Thanks to the work of Daniil Korostelev , Haxe now has the opportunity to generate ES6 classes for JavaScript. All you need to do is just add the compilation flag -D js-es=6



.







Currently, the compiler generates one js file for the entire project (it may be possible in the future to generate separate js files for each of the classes, but so far this can only be done using additional tools ).







image







For abstract enumerations, values ​​are now automatically generated.







In Haxe 3, it was necessary to manually set values ​​for each constructor. In Haxe 4, abstract enumerations created on top of Int



behave according to the same rules as in C. The abstract enumerations created on top of strings behave similarly - for them, the generated values ​​will coincide with the names of the constructors.







image







Some syntax improvements should also be mentioned:









image







The new syntax for describing function types (function type syntax) is more logical: the use of parentheses around the types of function arguments is visually easier to read. In addition, the new syntax allows you to define argument names, which can be used as part of the documentation for the code (although it does not affect the typing itself).







image







The old syntax continues to be supported and is not declared obsolete, because otherwise, it would require too many changes in the existing code (Simon himself constantly finds himself out of habit using the old syntax).







Haxe 4 finally has arrow functions (or lambda expressions)!







image







Features of arrow functions in Haxe are:









In general, the syntax of arrow functions is very similar to that used in Java 8 (although it works somewhat differently).







And since we mentioned Java, it should be said that in Haxe 4 it was possible to generate JVM bytecode directly. To do this, when compiling the project under Java, just add the -D jvm



flag.







Generating a JVM bytecode means that there is no need to use a Java compiler, and the compilation process is much faster.







image







So far, the JVM target has experimental status for the following reasons:









image







A general comparison of generating bytecode directly (genjvm) and compiling Haxe into Java code, which is then compiled into bytecode (genjava):









General tips for working with Java in Haxe:









The new Haxe 4 feature, Null safety, can help avoid using Null<T>



. Alexander Kuzmenko spoke in detail about her at last year's HaxeUp .







image







In the example on the slide above, the static safe()



method has the Strict mode for checking for Null security enabled, and this method has an optional arg



parameter, which can have a null value. In order for this function to compile successfully, the programmer will need to add a check of the arg



argument value (otherwise, the compiler will display a message about the impossibility of calling the charAt()



method on a potentially null object).







image







Null security can be configured both at the package level (using a macro) and types and individual fields of objects (using the @:nullSafety



meta tag).







The modes in which Null Security checks work are: Strict, Loose, and Off. Globally, these checks are disabled (Off-mode). When they are turned on, the Loose mode is used by default (unless you explicitly specify the mode). The key difference between Loose and Strict modes is that the Loose mode ignores the possibility of changing values ​​between operations of accessing these values. In the example on the slide below, we see that a null



check has been added for the variable x



. However, in Strict mode, this code does not compile, because before working directly with the variable x



, the sideEffect()



method is sideEffect()



, which can potentially nullify the value of this variable, so you will need to add another check or copy the value of the variable to a local variable, which we will continue to work with.







image







Haxe 4 introduces a new final



keyword, which has a different meaning depending on the context:









image







Theoretically, the compiler, having met the final



keyword, can try to optimize the code, assuming that the value of this field does not change. But for now, this possibility is only being considered and is not implemented in the compiler.







image







And a little about the future of Haxe:










All Articles