Haxe 3 New Features

Abstract types

  • Explanation: An abstract type is something that does not really exist at runtime, and is typically represented there by another, non-abstract type. Haxe 3 allows fine-grained semantic definitions of an abstract type, including implicit casts, operator overloading and custom array access.
  • Example:
  • More information: Abstract Types

Array comprehension

  • Explanation: The Array comprehension syntax of haxe 3 is focused on providing a concise mechanism of initializing Arrays, while still retaining readability, which is often neglected in other languages. The syntax revolves around already known for, while and if expressions inside a [ ] Array declaration.
  • Example:
    // even numbers from 0 to 20
    var a = [for (i in 0...21) if (i & 1 == 0) i];
    trace(a); // [0,2,4,6,8,10,12,14,16,18,20]
    
    // parts of a file path (using haxe.io.Path)
    var path = "/top/bar/foo/File.hx";
    var pathParts = [while ((path = haxe.io.Path.directory(path)) != "") path];
    trace(pathParts); // [/top/bar/foo,/top/bar,/top]

Generic functions

  • Explanation: Haxe 3 allows @:generic on function, which behaves exactly like its equivalent on classes: The function is specialized for each type parameter combination, which can yield performance improvements on static platforms. As a bonus, the type parameters can be constructed if they are constrained to having a new function.
  • Example:
        @:generic static function foo<T:{function new(s:String):Void;}>(t:T) {
            trace(Type.typeof(t)); // TClass([class String]) / TClass([class Template])
            return new T("foo");
        }
        
        static public function test() {
            var s = foo("foo");
            var t = foo(new haxe.Template("bar"));
            trace(s); // foo
            trace(t); // haxe.Template
        }

Map

  • Explanation: Haxe 2 provided map data structures for Int and String keys. With haxe 3 it is possible to use most objects as keys through a single, toplevel Map class. The generated code automatically uses data structures optimized for the chosen key type.
  • Example:
    // String keys with Int values
    var map = new Map();
    map.set("foo", 99);
    trace(map.get("foo")); // 99
    
    // Int keys with Int values
    var map = new Map();
    map.set(6, 7);
    trace(map.get(6)); // 7
    
    // Object keys with function value
    var http = new haxe.Http("haxe.org");
    var map = new Map();
    map.set(http, function() return "haxe.org");
    trace(map.get(http)()); // haxe.org

As a bonus, maps allow element access with the Array operator:

var map = new Map();
map["foo"] = 9;
trace(map["foo"]); // 9
map["foo"] += 12;
trace(map["foo"]); // 21

Also you can now use the "=>' operator as explained here:
Jason explains the => new feature

Macro reification

  • Explanation: While macro reification was around in haxe 2, it was lacking in some aspects and often required manual work. This was greatly improved in haxe 3, where macro reification is now very similar to String interpolation.
  • Example:
    var e1 = macro 4; // A normal 4 constant
    var e2 = macro $e1 + 2; // Binary operator 4 + 2;
    // haxe 3 only from here on
    var e3 = macro myFunc($a{[$e1, $e2]}); // a call to myFunc using 4 and 4 + 2 as arguments
    var e4 = macro $p{["haxe", "Log", "trace"]}; // a path to haxe.Log.trace
    var ident = "varName";
    var e5 = macro trace($i{ident}); // a call to trace with identifier varName as argument
    var e6 = macro $b{[e1,e2,e3,e4,e5]}; // a block of all the above

Pattern matching

  • Explanation: While enums have been a powerful ADT data structure throughout haxe's existence, it was quite verbose to switch over them in order to query for deep information. Haxe 3 pattern matching comes to the rescue here, allowing not only switching over nested enums, but also structures and arrays.
  • Example:
    var expr = macro someCall("1");
    switch(expr.expr) {
        case ECall({expr: EConst(CIdent("someCall")) }, [{expr: EConst(arg)}]):
            trace("Some call to: " +arg); // Some call to: CString(1)
        case _:
            trace ("No match");
    }
  • More information: Pattern Matching
version #19422, modified 2013-06-06 17:34:27 by JLM