6 Language Features

Abstract types:

An abstract type is a compile-time construct which is represented in a different way at runtime. This allows giving a whole new meaning to existing types.

Extern classes:

Externs can be used to describe target-specific interaction in a type-safe manner.

Anonymous structures:

Data can easily be grouped in anonymous structures, minimizing the necessity of small data classes.

 var point = {x: 0, y: 10}; point.x += 10; 

Array Comprehension:

Create and populate arrays quickly using for loops and logic.

 var evenNumbers = [for (i in 0...100) if (i & 1 == 0) i]; 

Map Comprehension:

Create and populate maps quickly using for loops and logic.

 var primality = [for (i in 0...100) i => isPrime(i)]; 

Classes, interfaces and inheritance:

Haxe allows structuring code in classes, making it an object-oriented language. Common related features known from languages such as Java are supported, including inheritance and interfaces.

Conditional compilation:

Conditional Compilation allows compiling specific code depending on compilation parameters. This is instrumental for abstracting target-specific differences, but can also be used for other purposes, such as more detailed debugging.

 #if js  js.Browser.alert("Hello"); #elseif sys  Sys.println("Hello"); #end 

(Generalized) Algebraic Data Types:

Structure can be expressed through algebraic data types (ADT), which are known as enums in the Haxe Language. Furthermore, Haxe supports their generalized variant known as GADT.

 enum Result {  Success(data:Array<Int>);  UserError(msg:String);  SystemError(msg:String, position:PosInfos); } 

Inlined calls:

Functions can be designated as being inline, allowing their code to be inserted at call-site. This can yield significant performance benefits without resorting to code duplication via manual inlining.

Iterators:

Iterating over a set of values, e.g. the elements of an array, is very easy in Haxe courtesy of iterators. Custom classes can quickly implement iterator functionality to allow iteration.

 for (i in [1, 2, 3]) {  trace(i); } 

Local functions and closures:

Functions in Haxe are not limited to class fields and can be declared in expressions as well, allowing powerful closures.

 var buffer = ""; function append(s:String) {  buffer += s; } append("foo"); append("bar"); trace(buffer); // foobar 

Metadata:

Add metadata to fields, classes or expressions. This can communicate information to the compiler, macros, or runtime classes.

 class MyClass {  @range(1, 8) var value:Int; } trace(haxe.rtti.Meta.getFields(MyClass).value.range); // [1,8] 

Static Extensions:

Existing classes and other types can be augmented with additional functionality through using static extensions.

 using StringTools; " Me & You ".trim().htmlEscape(); 

String Interpolation:

Strings declared with a single quotes are able to access variables in the current context.

 trace('My name is $name and I work in ${job.industry}'); 

Partial function application:

Any function can be applied partially, providing the values of some arguments and leaving the rest to be filled in later.

 var map = new haxe.ds.IntMap(); var setToTwelve = map.set.bind(_, 12); setToTwelve(1); setToTwelve(2); 

Pattern Matching:

Complex structures can be matched against patterns, extracting information from an enum or a structure and defining specific operations for specific value combination.

 var a = {foo: 12}; switch a {  case {foo: i}: trace(i);  default: } 

Properties:

Variable class fields can be designed as properties with custom read and write access, allowing fine grained access control.

 public var color(get,set); function get_color() {  return element.style.backgroundColor; } function set_color(c:String) {  trace('Setting background of element to $c');  return element.style.backgroundColor = c; } 

Access control:

The access control language feature uses the Haxe metadata syntax to force or allow access classes or fields.

Type Parameters, Constraints and Variance:

Types can be parametrized with type parameters, allowing typed containers and other complex data structures. Type parameters can also be constrained to certain types and respect variance rules.

 class Main<A> {  static function main() {  new Main<String>("foo");  new Main(12); // use type inference  }  function new(a:A) {} }