haxe 2 language reference

52
haXe 2 Language Reference (Last Updated: 24 Sep 2010) haXe2 1

Upload: dmitry-molchanov

Post on 09-Mar-2016

237 views

Category:

Documents


5 download

DESCRIPTION

haXe - universal programming language.

TRANSCRIPT

Page 1: haXe 2 Language Reference

haXe 2Language Reference

(Last Updated: 24 Sep 2010)

haXe2

1

Page 2: haXe 2 Language Reference

Table of Contents

1. Basic Types! 6

2. Syntax! 7

2.1. Constants! 7

2.2. Operations! 7

2.3. Unary operations! 8

2.4. Parentheses! 8

2.5. Blocks! 8

2.6. Local Variables! 9

2.8. Field access! 10

2.9. Calls! 10

2.10. New! 10

2.11. Arrays! 10

2.12. If! 11

2.13. While! 11

2.14. For! 12

2.15. Return! 12

2.16. Break and Continue! 13

2.17. Exceptions! 13

2.18. Switch! 14

2.19. Local Functions! 14

2.20. Anonymous Objects! 15

3. Type Inference! 16

3.1. Printing a Type! 16

3.2. Local variable inference! 16

haXe2

2

Page 3: haXe 2 Language Reference

3.3. Function types inference! 16

3.4. Inference and type parameters! 17

3.5. User Choice! 18

4. Object Oriented Programming! 19

4.1. Classes! 19

4.2. Constructor! 20

4.3. Class Inheritance! 20

4.4. Extends! 20

4.5. Implements! 21

4.6. Interfaces! 21

4.7. Helper Classes! 21

5. Type Parameters! 23

5.1. Constraint Parameters! 23

6. Enums! 24

6.1. Constructors parameters! 24

6.2. Switch on Enum! 25

6.3. Switch with Constructor Parameters! 25

6.4. Enum Type Parameters! 26

6.5. Using Enums as default value for parameters! 26

7. Packages and Imports! 27

7.1. Imports! 27

7.1.1. Applying additional static methods to class instances! 28

7.1.2. Importing a single type from a module! 28

7.1.3. Importing using wildcards ('*')! 29

7.2. Type Lookup! 29

7.3. Enum Constructors! 29

8. Dynamic! 30

8.1. Parameterized Dynamic Variables! 31

haXe2

3

Page 4: haXe 2 Language Reference

8.2. Implementing Dynamic! 31

8.3. Type Casting! 32

8.4. Untyped! 32

8.5. Unsafe Cast! 32

9. Advanced Types! 33

9.1. Anonymous! 33

9.2. Typedef! 33

9.2.1. As aliases! 34

9.2.2. Private members! 34

9.2.3. Private types! 35

9.2.4. Accessing Typedefs From Other Packages! 35

9.3. Functions! 35

9.4. Unknown! 36

9.5. Extensions! 36

10. Iterators! 38

10.1. Implementing Iterator! 38

10.2. Iterable Objects! 39

11. Properties! 40

11.1. Sample! 40

11.2. Important Remarks! 41

11.3. Dynamic Property! 41

11.4. Null Property! 42

11. 5. Never Property! 42

12. Optional Arguments! 44

12.1. Default values! 44

12.2. Ordering! 44

12.3. Enum Values! 45

12.4. Warning! 45

haXe2

4

Page 5: haXe 2 Language Reference

13. Conditional Compilation! 46

14. Inline! 47

14.1. Inlining Static Variables! 47

14.2. Inlining Methods! 47

15. Keywords! 49

haXe2

5

Page 6: haXe 2 Language Reference

1. Basic TypesThe haXe syntax is Java/ActionScript/C++ like.

A source code file is composed of an optional package name followed by several imports and type declarations. By convention, package names are composed of several identifiers each of which start with a lowercase letter and are separated from one another by periods ".", while type identifiers always start with an uppercase letter.

There are several kinds of types. The two important ones are classes and enums. Here are some of the basic types as declared in the standard library :

enum Void { }

class Float { }

class Int extends Float { }

enum Bool { true; false; }

enum Dynamic<T> { }

Let's see each type one by one :

1 Void is declared as an enum. An enumeration lists a number of valid constructors. An empty enumeration such as Void does not have any constructor. However, it's still a valid type that can be used.

2 Float is a floating point number class. It doesn't have any method so it can be greatly optimized on some platforms.

3 Int is an integer. It doesn't have methods either but it inherits from Float, so it means that everywhere a Float is requested, you can use an Int, while the contrary is not true. And that seems pretty correct.

4 Bool is an enumeration, like Void, but it has two instances true and false. As you can see, even standard types can be defined easily using the haXe type system. It also means you can use it to define your own types.

5 Dynamic is an enum with a type parameter. We will explain how to use type parameters later in this document.

haXe2

6

Page 7: haXe 2 Language Reference

2. SyntaxIn haXe, all expressions have the same level. It means that you can nest them together recursively without any problem. For example : foo(if (x == 3) 5 else 8). As this example shows, it also means that every expression returns a value of a given type.

2.1. Constants

The following constant values can be used :

0; // Int -134; // Int 0xFF00; // Int

123.0; // Float .14179; // Float 13e50; // Float -1e-99; // Float

"hello"; // String "hello \"world\" !"; // String 'hello "world" !'; // String

true; // Bool false; // Bool

null; // Unknown<0>

~/[a-z]+/i; // EReg : regular expression

You will notice that null has a special value that can be used for any type, and has different behavior than Dynamic. It will be explained in detail when introducing type inference.

2.2. Operations

The following operations can be used, in order of priority :

1 v = e : assign a value to an expression, returns e

2 += -= *= /= %= &= |= ^= <<= >>= >>>= : assign after performing the corresponding operation

3 e1 || e2 : If e1 is true then true else evaluate e2 . Both e1 and e2 must be Bool.

4 e1 && e2 : If e1 is false then false else evaluate e2 . Both e1 and e2 must be Bool.

5 e1...e2 : Build an integer iterator (see later about Iterators).

6 == != > < >= <= : perform normal or physical comparisons between two expressions sharing a common type. Returns Bool.

7 | & ^ : perform bitwise operations between two Int expressions. Returns Int.

haXe2

7

Page 8: haXe 2 Language Reference

8 << >> >>> : perform bitwise shifts between two Int expressions. Returns Int.

9 e1 + e2 : perform addition. If both expressions are Int then return Int else if both expressions are either Int or Float then return Float else return String.

10 e1 - e2 : perform subtraction between two Int or Float expressions. Return Int if both are Int and return Float if they are either Float and Int.

11 e1 * e2 : multiply two numbers, same return type as subtract.

12 e1 / e2 : divide two numbers, return Float.

13 e1 % e2 : modulo of two numbers, same return type as subtract.

2.3. Unary operations

The following unary operations are available :

1 ! : boolean not. Inverse the expression Bool value.

2 - : negative number, change the sign of the Int or Float value.

3 ++ and -- can be used before or after an expression. When used before, they first increment the corresponding variable and then return the incremented value. When used after, they increment the variable but return the value it had before incrementation. Can only be used with Int or Float values.

4 ~ : ones-complement of an Int.

Note: ~ is usually used for 32-bit integers, so it will not provide expectedresults with Neko 31-bits integers, that is why it does not work on Neko.

2.4. Parentheses

Expressions can be delimited with parentheses in order to give a specific priority when performing operations. The type of ( e ) is the same as e and they both evaluate to the same value.

2.5. Blocks

Blocks can execute several expressions. The syntax of a block is the following :

{ e1; e2; // ... eX; }

A block evaluates to the type and value of the last expression of the block. For example :

{ f(); x = 124; true; }

This block is of type Bool and will evaluate to true.

haXe2

8

Page 9: haXe 2 Language Reference

As an exception, the empty block { } evaluates to Void.

2.6. Local Variables

Local variables can be declared in blocks using var, as the following samples show:

{ var x; var y = 3; var z : String; var w : String = ""; var a, b : Bool, c : Int = 0; }

A variable can be declared with an optional type and an optional initial value. If no value is given then the variable is null by default. If no type is given, then the variable type is Unknown but will still be strictly typed. This will be explained in details when introducing type inference.

Several local variables can be declared in the same var expression.

Local variables are only defined until the block they're declared in is closed. They can not be accessed outside the block in which they are declared.

2.7. Identifiers

When a variable identifier is found, it is resolved using the following order :

1 local variables, last declared having priority

2 class members (current class and inherited fields)

3 current class static fields

4 enum constructors that have been either declared in this file or imported enum Axis { x; y; z; }

class C { static var x : Int; var x : Int;

function new() { { // x at this point means member variable this.x var x : String; // x at this point means the local variable } }

function f(x : String) {

haXe2

9

Page 10: haXe 2 Language Reference

// x at this point means the function parameter }

static function f() { // x at this point means the class static variable } }

class D { function new() { // x means the x Axis } }

Type identifiers are resolved according to the imported packages, as we will explain later.

2.8. Field access

Object access is done using the traditional dot-notation :

o.field

2.9. Calls

You can call functions using parentheses and commas in order to delimit arguments. You can call methods by using dot access on objects :

f(1,2,3); object.method(1,2,3);

2.10. New

The new keyword is used in expressions to create a class instance. It needs a class name and can take parameters :

a = new Array(); s = new String("hello");

2.11. Arrays

You can create arrays directly from a list of values by using the following syntax :

var a : Array<Int> = [1,2,3,4];

Please notice that the type Array takes one type parameter that is the type of items stored into the Array. This way all operations on arrays are safe. As a consequence, all items in a given Array must be of the same type.

haXe2

10

Page 11: haXe 2 Language Reference

You can read and write into an Array by using the following traditional bracket access :

first = a[0]; a[1] = value;

The array index must be of type Int.

2.12. If

Here are some examples of if expressions :

if (life == 0) destroy(); if (flag) 1 else 2;

Here's the generic syntax of if expressions :

if( expr-cond ) expr-1 [else expr-2]

First expr-cond is evaluated. It must be of type Bool. Then if true then expr-1 is evaluated, otherwise, if there is an expr-2 then it is evaluated instead.

If there is no else, and the if expression is false, then the entire expression has type Void. If there is an else, then expr-1 and expr-2 must be of the same type and this will be the type of the if expression :

var x : Void = if( flag ) destroy(); var y : Int = if( flag ) 1 else 2;

In haXe, if is similar to the ternary C a?b:c syntax.

As an exception, if an if block is not supposed to return any value (like in the middle of a Block) then both expr-1 and expr-2 can have different types and the if block type will be Void.

2.13. While

While are standard loops that use a precondition or postcondition :

while( expr-cond ) expr-loop; do expr-loop while( expr-cond );

For example :

var i = 0; while( i < 10 ) { // ... i++; }

haXe2

11

Page 12: haXe 2 Language Reference

Or using do...while :

var i = 0; do { // ... i++; } while( i < 10 );

Like with if, the expr-cond in a while-loop type must be of type Bool.

Another useful example will produce a loop to count from 10 to 1:

var i = 10; while( i > 0 ) { ....... i--; }

2.14. For

For loops are little different from traditional C for loops. They're actually used for iterators, which will be introduced later in this document. Here's an example of a for loop :

for( i in 0...a.length ) { foo(a[i]); }

2.15. Return

In order to exit from a function before the end or to return a value from a function, you can use the return expression :

function odd( x : Int ) : Bool { if( x % 2 != 0 ) return true; return false; }

The return expression can be used without argument if the function does not require a value to be returned :

function foo() : Void { // ... if( abort ) return; // .... }

haXe2

12

Page 13: haXe 2 Language Reference

2.16. Break and Continue

These two keywords are useful to exit early a for or while loop or to go to the next iteration of a loop :

var i = 0; while( i < 10 ) { if( i == 7 ) continue; // skip this iteration. // do not execute any more statements in this block, // BUT go back to evaluating the "while" condition. if( flag ) break; // stop early. // Jump out of the "while" loop, and continue // execution with the statement following the while loop. }

2.17. Exceptions

Exceptions are a way to do non-local jumps. You can throw an exception and catch it from any calling function on the stack :

function foo() { // ... throw new Error("invalid foo"); }

// ...

try { foo(); } catch( e : Error ) { // handle exception }

There can be several catch blocks after a try, in order to catch different types of exceptions. They're tested in the order they're declared. Catching Dynamic will catch all exceptions :

try { foo(); } catch( e : String ) { // handle this kind of error } catch( e : Error ) { // handle another kind of error } catch( e : Dynamic ) { // handle all other errors }

All the try and the catch expressions must have the same return type except when no value is needed (same as if).

haXe2

13

Page 14: haXe 2 Language Reference

2.18. Switch

Switches are a way to express multiple if...else if... else if test on the same value:

if( v == 0 ) e1 else if( v == foo(1) ) e2 else if( v == 65 || v == 90 ) e3 else e4;

Will translate to the following switch :

switch( v ) { case 0: e1; case foo(1): e2; case 65, 90: e3; default: e4; }

Note: In the example above, a case statement reads "65, 90". This is an example where a case expects to match either of the two (or several) values, listed as delimited by comma(s).

Switches in haXe are different from traditional switches : all cases are separate expressions so after one case expression is executed the switch block is automatically exited. As a consequence, break can't be used in a switch and the position of the default case is not important.

On some platforms, switches on constant values (especially constant integers) might be optimized for better speed.

Switches can also be used on enums with a different semantic. It will be explained later in this document.

2.19. Local Functions

Local functions are declared using the function keyword but they can't have a name. They're values just like literal integers or strings :

var f = function() { /* ... */ }; f(); // call the function

haXe2

14

Page 15: haXe 2 Language Reference

Local functions can access their parameters, the current class statics and also the local variables that were declared before it :

var x = 10; var add = function(n) { x += n; }; add(2); add(3); // now x is 15

However, local functions declared in methods cannot access the this value. You then need to declare a local variable such as me :

class C {

var x : Int;

function f() { // WILL NOT COMPILE var add = function(n) { this.x += n; }; }

function f2() {

// will compile var me = this; var add = function(n) { me.x += n; }; } }

2.20. Anonymous Objects

Anonymous objects can be declared using the following syntax :

var o = { age : 26, name : "Tom" };

Please note that because of type inference, anonymous objects are also strictly typed.

haXe2

15

Page 16: haXe 2 Language Reference

3. Type InferenceType Inference means that the type information is not only checked in the program, it's also carried when typing, so it doesn't have to be resolved immediately. For example a local variable can be declared without any type (it will have the type Unknown) and when first used, its type will be set to the corresponding one.

3.1. Printing a Type

Anywhere in your program, you can use the type operation to know the type of a given expression. At compilation, the type operation will be removed and only the expression will remain :

var x : Int = type(0);

This will print Int at compilation, and compile the same program as if type was not used.

This is useful to quickly get a type instead of looking at the class or some documentation.

3.2. Local variable inference

Type Inference enables the whole program to be strictly typed without any need to put types everywhere. In particular, local variables do not need to be typed, their types will be inferred when they are first accessed for reading or writing :

var loc; type(loc); // print Unknown<0> loc = "hello"; type(loc); // print String

3.3. Function types inference

Declaring the type of parameter passed to a class method or local function is also optional. The first time the function is used, the type of the parameter will be set to the type it was used with, just like local variables. This can be tricky since it will depend on the order in which the program is executed. Here's an example that shows the problem :

function f( posx ) { // .... } // ...

f(134); f(12.2); // Error : Float should be Int

The first call to f sets the type of posx to Int. The second call to f causes a compilation error because f is now expecting an Int, not a Float. However if we reverse the two calls to f, the value type is set to Float first. A second call using an Int does not fail since Int is a subtype of Float.

haXe2

16

Page 17: haXe 2 Language Reference

function f( posx ) { // .... } // ... f(12.2); // Sets the parameter type to Float f(134); // Success

In this example the two calls are near each other so it's quite easy to understand and fix. In larger programs with more complex cases, fixing such compilation problems can be tricky. The easiest solution is to explicitly set the type of the function. Then the call that was responsible for the problem will be displayed when recompiling.

Drawing from the first example:

function f( posx : Int ) { // .... } // ...

f(134); f(12.2); // Failure will point to this line

3.4. Inference and type parameters

function f<T>(p: Class<T>): T{

}

function g(p: Float){

}

var a: Dynamic = {};

var b = f(a);

type(b); //At this point the type of 'b' is not inferred and is traced as 'Unknown<0>'

g(b);

type(b); //Type of 'b' is from now on known to be 'Float'

The code above illustrates a situation with a function call that initializes a variable declared without type - the type inferring does not occur at that point, because the combination of the function being called and call parameters makes it impossible. The 'type parametrized' function f depends on its first parameter of type Class<T> (T being an abstract, see "Type parameters" doc. page), to decide what type it returns. When passed a Dynamic object however, it is clear that the type parameter 'T' makes no sense and is unknown. Type inferring is delayed until further, when a call to g that takes a Float is able to tell the compiler to specify type of b as Float. Hence the first type

haXe2

17

Page 18: haXe 2 Language Reference

statement traces "Unknown<0>" and the second - "Float". After the type is inferred, it is naturally immutable.

3.5. User Choice

Using type inference is a choice. You can simply not type your variables and functions and let the compiler infer the types for you, or you can type all of them in order to have more control on the process. The best is maybe in the middle, by adding some typing in order to improve code documentation and still be able to write quickly some functions without typing everything.

In all cases, and unless you use dynamics (they will be introduced later), your program will be strictly typed and any wrong usage will be detected instantly at compilation.

haXe2

18

Page 19: haXe 2 Language Reference

4. Object Oriented Programming4.1. Classes

We will quickly introduce the structure of classes that you might already be familiar with if you've done some OO programming before :

package my.pack; /* this will define the class my.pack.MyClass */ class MyClass { // .... }

A Class can have several variables and methods.

package my.pack;

class MyClass {

var id : Int;

static var name : String = "MyString";

function foo() : Void { }

static function bar( s : String, v : Bool ) : Void { } }

Variables and methods can have the following flags :

1 static : the field belongs to the Class itself and not to instances of this class. Static identifiers can be used directly in the class itself. Outside of the class, it must be used with the class name (for example : my.pack.MyClass.name).

2 dynamic: the field can be dynamically rebound.

3 override: the field is being overridden in a subclass.

4 public : the field can be accessed from outside of the class.

5 private : the field access is restricted to the class itself and to classes that subclass or extends it. This ensures that the class internal state is not accessible.By default, all fields are private. This corresponds to the keyword protected in most other languages such as Java, PHP

All class variables must be declared with a type (you can use Dynamic if you don't know which type to use). Function arguments and return types are optional but are still strictly checked as we will see when introducing type inference.

haXe2

19

Page 20: haXe 2 Language Reference

Non-static variables may not have an initial value. Static variables can have an initial value, although it is not required.

4.2. Constructor

The class can have only one constructor, which is the not-static function called new. This is a keyword that can also be used to name a class function :

class Point { public var x : Int; public var y : Int;

public function new() { this.x = 0; this.y = 0; } }

Constructor parametrization & overloading :

public function new( x : Int, ?y : Int ) { this.x = x; this.y = (y == null) ? 0 : y; // "y" is optional }

4.3. Class Inheritance

When declared, it's possible that a class extends one class and implements several classes or interfaces. This means the class will inherit several types at the same time, and can be treated as such. For example :

class D extends A, implements B, implements C { }

Every instance of D will have the type D but you will also be able to use it where an instance of type A, B or C is required. This means that every instance of D also has the types A , B and C.

4.4. Extends

When extending a class, your class inherits from all public and private non-static fields. You can then use them in your class as if they where declared here. You can also override a method by redefining it with the same number of arguments and types as its superclass. Your class can not inherit static fields.

haXe2

20

Page 21: haXe 2 Language Reference

When a method is overridden, then you can still access the superclass method using super :

class B extends A { override function foo() : Int { return super.foo() + 1; } }

In your class constructor you can call the superclass constructor using also super :

class B extends A { function new() { super(36,""); } }

4.5. Implements

When implementing a class or an interface, your class is required to implement all the fields declared or inherited by the class it implements, with the same type and name. However the field might already be inherited from a superclass.

4.6. Interfaces

An Interface is an abstract type. It is declared using the interface keyword. By default, all interface fields are public. Interfaces cannot be instantiated.

interface PointProto { var x : Int; var y : Int; function length() : Int; }

An interface can also implement one or several interfaces :

interface PointMore implements PointProto { function distanceTo( p : PointProto ) : Float; }

4.7. Helper Classes

In haXe, it is possible to have more than one class definition per class file:

// both definitions in Foo.hxclass Foo { ... }class FooHelper { ... }

This is fairly common in many object oriented languages such as Java. However, unlike other such languages, haXe also allows for these internal helper classes to be publicly available outside of the main class. By importing the main class, the helper class becomes available:

haXe2

21

Page 22: haXe 2 Language Reference

// in Bar.hximport Foo;class Bar{ var b:FooHelper;}

The helper class can also be made accessible via an extended package declaration:

// in Bar.hxclass Bar{ var b:Foo.FooHelper;}

The use of public internal helper classes is typically not a recommended practice in most languages. Since helper class names do not correspond with their .hx file names, they can be harder to find in source trees.

HaXe lets you mark an internal helper class with the private keyword, in the same way that fields are marked:

// both definitions in Foo.hxclass Foo { ... }private class FooHelper { ... }

This prevents the internal helper class from being accessed outside of the main class.

Unless there is a good reason for their use, consider placing each public class definition in its own .hx file, or make the internal class private, to prevent its definitions being included (and possibly causing a name conflict) when the main class is imported.

haXe2

22

Page 23: haXe 2 Language Reference

5. Type ParametersA class can have several type parameters that can be used to get extensible behavior. For example, the Array class has one type parameter:

class Array<T> {

function new() { // ... }

function get( pos : Int ) : T { // ... }

function set( pos : Int, val : T ) : Void { // ... } }

Inside the Array class, the type T is abstract which means its fields and methods are not accessible. However when you declare an array you need to specify its type : Array<Int> or Array<String> for example. This will act the same as if you had replaced all types T in the Array declaration by the type you're specifying.

The type parameter is very useful in order to get strict typing of containers such as Array, List, and Tree. You can define your own parameterized classes with several type parameters for your own usage when you need it.

5.1. Constraint Parameters

While it's nice to be able to define abstract parameters, it is also possible to define several constraints on them in order to be able to use them in the class implementation. For example :

class EvtQueue<T : (Event, EventDispatcher)> { var evt : T; // ... }

In this class, although the field evt is a class paramater, the typer knows that it has both types Event and EventDispatcher so it can actually access it like if it was implementing both classes. Later, when an EvtQueue is created, the typer will check that the type parameter either extends or implements the two types Event and EventDispatcher. When multiple constraint parameters are defined for a single class parameter, as in the example above, they should be placed within parenthesis in order to disambiguate from cases where more class parameters are to follow.

Type parameter constraints are a powerful feature that lets a developer write generic code that can be reused across different applications.

haXe2

23

Page 24: haXe 2 Language Reference

6. EnumsEnums are different to classes and are declared with a finite number of constructors. Here's a small example:

enum Color { red; green; blue; }

class Colors { static function toInt( c : Color ) : Int { return switch( c ) { case red: 0xFF0000; case green: 0x00FF00; case blue: 0x0000FF;

} } }

When you want to ensure that only a fixed number of values are used then enums are the best thing since they guarantee that other values cannot be constructed.

6.1. Constructors parameters

The previous Color sample shows three constant constructors for an enum. It is also possible to have parameters for constructors :

enum Color2 { red; green; blue; grey( v : Int ); rgb( r : Int, g : Int, b : Int ); }

This way, there is an infinite number of Color2's possible, but there are five different constructors possible for it. The following values are all Color2:

red; green; blue; grey(0); grey(128); rgb( 0x00, 0x12, 0x23 ); rgb( 0xFF, 0xAA, 0xBB );

haXe2

24

Page 25: haXe 2 Language Reference

We can also have a recursive type, for example to add alpha :

enum Color3 { red; green; blue; grey( v : Int ); rgb( r : Int, g : Int, b : Int ); alpha( a : Int, col : Color3 ); }

The following are valid Color3 values :

alpha( 127, red ); alpha( 255, rgb(0,0,0) );

6.2. Switch on Enum

A switch has a special behavior when used on an enum. If there is no default case then it will check that all an enum's constructors are used within the switch, and if not the compiler will generate a warning. For example, consider the first Color enum :

switch( c ) { case red: 0xFF0000; case green: 0x00FF00; }

This will cause a compile error warning that the constructor blue is not used. In this example you can either add a case for it or add a default case that does something. This can be quite useful, as when you add new constructors to your enum, compiler errors will alert you to areas in your program where the new constructor should be handled.

6.3. Switch with Constructor Parameters

If enum constructor have parameters, they must be listed as variable names in a switch case. This way all the variables will be locally accessible in the case expression and correspond to the type of the enum constructor parameter. For example, using the Color3 enum:

class Colors { static function toInt( c : Color3 ) : Int { return switch( c ) { case red: 0xFF0000; case green: 0x00FF00; case blue: 0x0000FF; case grey(v): (v << 16) | (v << 8) | v; case rgb(r,g,b): (r << 16) | (g << 8) | b; case alpha(a,c): (a << 24) | (toInt(c) & 0xFFFFFF); } }

}

haXe2

25

Page 26: haXe 2 Language Reference

Using switch is the only possible way to access the enum constructors parameters.

6.4. Enum Type Parameters

An Enum can also have type parameters. The syntax is the same so here's a small sample of a parameterized linked List using an enum to store the cells :

enum Cell<T> { empty; cons( item : T, next : Cell<T> ); }

class List<T> { var head : Cell<T>;

public function new() { head = empty; }

public function add( item : T ) { head = cons(item,head); }

public function length() : Int { return cell_length(head); }

private function cell_length( c : Cell<T> ) : Int { return switch( c ) { case empty : 0; case cons(item,next): 1 + cell_length(next); } }

}

Using both enums and classes together can be pretty powerful in some cases.

6.5. Using Enums as default value for parameters

Because an Enum's values are in fact created from a constructor they are not constant and therefore cannot be used as default value for a parameter. However there's a simple work-around :

enum MyEnum { myFirstValue; mySecondValue; }

haXe2

26

Page 27: haXe 2 Language Reference

class Test { static function withDefaultValuesOnParameters(?a : MyEnum) ! { if(a == null) a = MyEnum.myFirstValue; } }

7. Packages and ImportsEach file can contain several classes, enums and imports. They are all part of the package declared at the beginning of the file. If package is not declared then the default empty package is used. Each type has then a path corresponding to the package name followed by the type name.

// file my/pack/C.hx package my.pack;

enum E { }

class C { }

This file declares two types : my.pack.E and my.pack.C. It's possible to have several classes in the same file, but the type name must be unique in the whole application, so conflicts can appear if you're not using packages enough (this does not mean that you have to use long packages names everywhere).

When creating types using packages, you should create a nested folder/directory structure matching the package name, and your files defining the type should be created in the innermost folder/directory. The name of the file should generally match the type you are creating. For example, to create the types E and C, in the package my.pack as shown above, your folder structure should be my\pack and the files could be E.hx and C.hx in the folder pack. In general, the name of the file is the one containing the definition of the main class.

The file extension for haXe is .hx.

Each part of the path in package names must begin with a lower case letter and, like all types, type names in packages must begin with an upper case letter. Hence My.Pack is an invalid package, as is my.Pack. Similarly, my.pack.e would not be a valid type name or import.

7.1. Imports

Imports can be used to have access to all the types of a file without needing to specify the package name.

haXe2

27

Page 28: haXe 2 Language Reference

package my.pack2; class C2 extends my.pack.C { }

Is identical to the following :

package my.pack2; import my.pack.C;

class C2 extends C { }

The only difference is that when using import you can use enum constructors that were declared in the my/pack/C.hx file.

7.1.1. Applying additional static methods to class instances

The using keyword imports a file, additionally applying all static methods from that file as member functions on the type of their first parameter.Say we have:

package my.pack; class StringUtils { public function double( string:String ):String { return string + string; } }

Then one could import the class and double a string:

import my.pack.StringUtils;

StringUtils.double( "Hello!"); // returns "Hello!Hello!"

Or, equivalently:

using my.pack.StringUtils;

"Hello!".double(); // returns "Hello!Hello!"

7.1.2. Importing a single type from a module

Given a module containing multiple types, such as

package my.pack2; typedef A = { a : String } typedef B = { b : String }

it is possible to import one type at a time from that module, using the following syntax:

import my.pack2.A;

haXe2

28

Page 29: haXe 2 Language Reference

7.1.3. Importing using wildcards ('*')

Importing multiple types with wildcards is NOT supported in haXe, i.e.

import flash.display.*;

will result in compiler error, quote "x.hx:1: characters x-x : Unexpected *".

7.2. Type Lookup

When a type name is found, the following lookup is performed, in this order:

1 current class type parameters

2 standard types

3 types declared in the current file

4 types declared in imported files (if the searched package is empty)

5 if not found, the corresponding file is loaded and the type is searched inside it

7.3. Enum Constructors

In order to use enum constructors, the file in which the enum is declared must first be imported, or you can use the full type path to access constructors as if they were static fields of the enum type.

var c : my.pack.Color = my.pack.Color.red;

As an exception, in switch: if the type of the enum is known at compile time, then you can use constructors directly without the need to import.

haXe2

29

Page 30: haXe 2 Language Reference

8. DynamicDisclaimer: Dynamic variables are often necessary to ensure interoperability with third party or platform dependent libraries, or for very specific cases where dynamic variables are absolutely required. Their use is not encouraged for normal use, as their behavior differs between targets.

When you want to get some dynamically typed behavior and break free from the type system, you can use the Dynamic type which can be used in place of any type without any compile-time type-checking:

var x : Dynamic = ""; x = true; x = 1.744; x = {}; x.foo = 'bar'; x = new Array();

When a variable is marked "Dynamic" the compiler does not ensure that types are followed for a given variable. This means that it is possible to switch from referencing one type of object to another. Also, any assignment, field assignment, or index access will succeed at compile time.

At run time however, different targets may not recognize or even allow certain operations on certain variables. For instance, on the flash9 (AVM2 target) a dynamic variable is assigned a value, such as an integer or boolean an exception will be thrown. On less strict platforms (such as javascript) an error may not be thrown, but the value will not be saved.

var x:Dynamic = 4;x.foo = "Bar";

//flash9: ReferenceError: Error #1056: Cannot create property foo on Number.

//JS: foo.x = null;

Having an object 'implement Dynamic', allowing fields to be added/removed at runtime, is quite a different concept. See 'Implementing Dynamic' below.

Trying to modify the fields of a flash9 MovieClip instance will work (since it itself implements a Dynamic type), but modifying the fields of a flash9 Sprite class will cause a run time reference error:

// flash9var m:Dynamic = new flash.display.MovieClip();m.foo = "Bar";trace(m.foo); // value is saved var s:Dynamic = new flash.display.Sprite();s.foo = "Bar"; // ReferenceError!

haXe2

30

Page 31: haXe 2 Language Reference

In short, "Dynamic" variables never check for type by the compiler, whether they are assigned in a method body, or as a method argument. But, they still will observe run-time type restrictions that are in place for a given target, and may cause run-time errors.

An untyped variable is of type Unknown and not Dynamic. That is, an untyped variable does not have a type until it is determined by type inference. A Dynamic variable has a specific type: an any type.

8.1. Parameterized Dynamic Variables

Adding a parameter to a Dynamic type allows arbitrary access and assignment to any field as long as it is the same type as the parameter. For instance, Dynamic<String> allows access or assignment to any field, as long as these accesses accept or produce String types. This is useful to encode Hashtables where items are accessed using dot syntax:

var att : Dynamic<String> = xml.attributes; att.name = "Nicolas"; att.age = "26"; // ...

or var foo : Dynamic<String> = cast {}; foo.name = "Nicolas";

8.2. Implementing Dynamic

Any class can also implement Dynamic with or without a type parameter. In the first case, the class fields are typed when they exist, otherwise they have a dynamic type:

class C implements Dynamic<Int> { public var name : String; public var address : String;}// ...var c = new C();var n : String = c.name; // okvar a : String = c.address; // okvar i : Int = c.phone; // ok : use Dynamicvar c : String = c.country; // ERROR// c.country is an Int because of Dynamic<Int>

Dynamic behavior is inherited by subclasses. When several classes are implementing different Dynamic types in a class hierarchy, the last Dynamic definition is used.

In the case of accessing an undefined property on an object which implements Dynamic the function "resolve" will be called. This function is called with one parameter, the property attempted to be accessed, and can return any value.

haXe2

31

Page 32: haXe 2 Language Reference

8.3. Type Casting

You can cast from one type to another by using the cast keyword.

var a : A = .... var b : B = cast(a,B);

This will either return the value a with the type B if a is an instance of B or it will throw an exception "Class cast error".

8.4. Untyped

One other way to do dynamic things is to use the untyped keyword. When an expression is untyped, no type-check will be done so you can execute many dynamic operations at once:

untyped { a["hello"] = 0; }

Be careful to use untyped expressions only when you really need them and when you know what you're doing.

8.5. Unsafe Cast

The untyped keyword provides great flexibility at the cost of allowing potentially invalid syntax on the right side of the untyped keyword. It also allows for an unsafe cast which is similar to the standard cast except that no type is specified. That means that the cast call will not result in any runtime check, but will allow you to "lose" one type.

var y : B = cast 0;

An unsafe cast is similar to storing a value in a temporary Dynamic variable :

var tmp : Dynamic = 0; var y : B = tmp;

haXe2

32

Page 33: haXe 2 Language Reference

9. Advanced TypesUp to now, we have seen the following types :

1 class instance

2 enum instance

3 dynamic

There are several additional important types.

9.1. Anonymous

An anonymous type is the type of an anonymously declared object. It is also the type of a Class identifier (corresponding to all the static fields) or an Enum identifier (listing all the constructors). Here's an example that shows it:

enum State { on; off; disable; }

class C { static var x : Int; static var y : String;

function f() { // print { id : Int, city : String } type({ id : 125, city : "Kyoto" }); }

function g() { // print { on : State, off : State, disable : State } type(State); }

function h() { // print { x : Int, y : String } type(C); } }

9.2. Typedef

You can define type definitions which are a kind of type shortcut that can be used to give a name to an anonymous type or a long type that you don't want to repeat everywhere in your program :

typedef User = { var age : Int; var name : String;}// ....

haXe2

33

Page 34: haXe 2 Language Reference

var u : User = { age : 26, name : "Tom" };

// PointCube is a 3-dimensional array of pointstypedef PointCube = Array<Array<Array<Point>>>

Typedefs are not classes, they are only used for typing.

9.2.1. As aliases

You can "alias" types using type definitions in the following manner:

class MyClassWithVeryLongName { }typedef MyClass = MyClassWithVeryLongName;

You can assign any kind of type like this, not just classes - enums, interfaces and other type definitions can be aliased as well in the similiar manner. The resulting type identifiers can be used wherever you would otherwise be using the class, enum, or whatever.

9.2.2. Private members

Typedefs can contain private members in their definitions. This allows access to otherwise unavailable members.

class Foo { public function new() {} public function fullAccess() return true function restrictedAccess() return true}

typedef Bar = { function fullAccess():Bool; private function restrictedAccess():Bool;}

class Main { public static function main() { var foo = new Foo(); foo.fullAccess(); //Compiler Error: Cannot access to private //field restrictedAccess foo.restrictedAccess(); var bar:Bar = foo; bar.fullAccess(); //No Error, this is allowed bar.restrictedAccess(); }}

haXe2

34

Page 35: haXe 2 Language Reference

9.2.3. Private types

A type - class, typedef, interface or enum - can be defined as 'private', which will confine its visibility only to the module it is defined in. Public types belong to packages they are defined in, and they can only be defined once. With private type definitions however you can have a "local" type only visible within the module it is defined in. Another private type with the same name and in the same package can be defined in another module.

private typedef MyType ={

}

9.2.4. Accessing Typedefs From Other Packages

It is often useful to use a typedef from another package for a variable declaration. This can be accomplished in the same ways that internal helper classes are referenced. For a given typedef "MyType":

// in Foo.hxprivate typedef MyType ={ ... }

The first way is to simply import the Class containing the Typedef you wish to use:

// in Bar.hximport Foo;class Bar{ var mt:MyType;}

The second way is to use a special extended package definition, which allows you to avoid using import:

// in Bar.hxclass Bar{ var mt:Foo.MyType;}

9.3. Functions

When you want to define function types to use them as variables, you can define them by listing the arguments followed by the return type and separated with arrows. For example Int -> Void is the type of a function taking an Int as argument and returning Void. Color -> Color ->Int takes two Color arguments and returns an Int.

class C { function f(x : String) : Int { // ... }

function g() {

haXe2

35

Page 36: haXe 2 Language Reference

type(f); // print String -> Int var ftype : String -> String = f; // ERROR : should be String -> Int } }

9.4. Unknown

When a type is not declared, it is used with the type Unknown. The first time it is used with another type, it will change to it. This was explained in more details in type inference. The id printed with the Unknown type is used to differentiate several unknowns when printing a complex type.

function f() { var x; type(x); // print Unknown<0> x = 0; type(x); // print Int }

The diversity of types expressible with haXe enable more powerful models of programming by providing high-level abstractions that don't need complex classes relationships to be used.

9.5. Extensions

Extensions can be used to extend either a typedef representing an anonymous type or to extend a class on-the-fly.

Here's an example of anonymous typedef extension :

typedef Point = { var x : Int; var y : Int; }

// define 'p' as a Point with an additional field z var p : {> Point, z : Int } p = { x : 0, y : 0, z : 0 }; // works p = { x : 0, y : 0 }; // fails

For classes, since they don't define types, you need to use a cast when assigning, it's unsafe so be careful :

var p : {> flash.MovieClip, tf : flash.TextField }; p = flash.Lib._root; // fails p = cast flash.Lib._root; // works, but no typecheck !

haXe2

36

Page 37: haXe 2 Language Reference

You can also use extensions to create cascading typedefs :

typedef Point = { var x : Int; var y : Int; } typedef Point3D = {> Point, var z : Int; }

In that case, every Point3D will of course be a Point as well.

Cascading typedefs can be created from normal class types as well, but the compiler will not be able to match this typedef against an anonymous object, or any other instanced class. This is because haXe is not fully structurally subtyped. Structural subtyping can only occur between anonymous typedefs or between an instance and an anonymous typedef.

haXe2

37

Page 38: haXe 2 Language Reference

10. IteratorsAn iterator is an object which follows the Iterator typedef (The type T is the iterated type) :

typedef Iterator<T> = { function hasNext() : Bool; function next() : T; }

You can use the for syntax in order to execute iterators. The simplest iterator is the IntIter iterator which can easily be built using the operator ... (three dots). For example this will list all numbers from 0 to 9 :

for( i in 0...10 ) { // ... }

Or the usual for loop :

for( i in 0...arr.length ) { foo(arr[i]); }

You don't need to declare the variable i before using a for, since it will be automatically declared. This variable will only be available inside the for loop and cannot be modified within the loop.

10.1. Implementing Iterator

You can also define you own iterators. You can simply follow the Iterator typedef in your class by implementing the hasNext and next methods. Here is for example the IntIter class that is part of the standard library :

class IntIter { var min : Int; var max : Int;

public function new( min : Int, max : Int ) { this.min = min; this.max = max; }

public function hasNext() { return( min < max ); }

public function next() { return min++; }}

haXe2

38

Page 39: haXe 2 Language Reference

Once your iterator is implemented, you can simply use it with the for...in syntax, this way :

var iter = new IntIter(0,10); for( i in iter ) { // ... }

The variable name in the for is automatically declared and its type is bound to the iterator type. It is not accessible after the iteration is done.

10.2. Iterable Objects

If an object has a method iterator() taking no arguments and returning an iterator, it is said to be iterable. It doesn't have to implement any type. You can use a class directly in a for expression without the need to call the iterator() method:

var a : Array<String> = ["hello","world","I","love","haXe","!"]; for( txt in a ) { tf.text += txt + " "; }

This sample will build the string by listing an array element using an iterator. It is the same as calling a.iterator() in the for expression.

haXe2

39

Page 40: haXe 2 Language Reference

11. PropertiesProperties are a specific way to declare class fields, and can be used to implement several kinds of features such as read-only/write-only fields or fields accessed through getter-setter methods.

Here's a property declaration example :

class C {

public var x(getter,setter) : Int;

}

The values for getter and setter can be one of the following :

1 a method name that will be used as getter/setter

2 null if the access is restricted from anywhere but its class' methods (see more below)

3 default if the access is a classic field access

4 dynamic if the access is done through a runtime-generated method

5 never if the access is never allowed, not even by means of Reflection

11.1. Sample

Here's a complete example :

class C { public var ro(default,null) : Int; public var wo(null,default) : Int; public var x(getX,setX) : Int; public var y(getX,never) : Int; // here y should always equal x

private var my_x : Int;

private function getX():Int { return my_x; }

private function setX( v : Int ):Int { if( v >= 0 ) my_x = v; return my_x; }

}

haXe2

40

Page 41: haXe 2 Language Reference

Using property declarations, we declare four public fields in the class C :

1 outside the class code, the field ro is read only

2 outside the class code, the field wo is write only

3 the field x is accessed through a pair of getter/setter methods

4 the field y can never be set, not even from code within the same class

For instance, the following two functions are equivalent, although the methods getX and setX are private and then can't be accessed directly as in f2 :

var c : C; function f1() { c.x *= 2; } function f2() { c.setX(c.getX()*2); }

11.2. Important Remarks

It's important to know that such features only work if the type of the class is known. There is no runtime properties handling, so for instance the following code will always trace null since the method getX will never be called :

var c : Dynamic = new C(); trace(c.x);

The same goes for read-only and write-only properties. They can always be modified if the type of the class is unknown.

Also, please note that you have to return a value from the setter function. The compiler will complain otherwise.

11.3. Dynamic Property

The additional dynamic access can be used to add methods at runtime, it's quite a specific feature that should be used with care. When a dynamic field x is accessed for reading, the get_x method is called, when accessed for writing the set_x method is called :

class C { public var age(dynamic,dynamic) : Int; public function new() { }}

class Test { static function main() { var c = new C(); var my_age = 26;

haXe2

41

Page 42: haXe 2 Language Reference

Reflect.setField(c,"get_age",function() { return my_age; }); Reflect.setField(c,"set_age",function(a) { my_age = a; return my_age; }); trace(c.age); // 26 c.age++; // will call c.set_age(c.get_age()+1) trace(c.age); // 27 }}

11.4. Null Property

Unlike initial expectations, null setter specification does not deny all access to the property, as is evidenced with the following example, which indeed succeeds to set the propertys value from within any class' own method(s):

class Main{ static function main() { var foo = new Foo(); /// Naturally, fails - write access denied from here. foo.prop = 1; Foo.set_prop_value(foo, 1); /// Succeeds. }}

class Foo{ static public function set_prop_value(foo: Foo, value: Int) { /// Will actually set the value of 'prop' indeed. foo.prop = value; }

public var prop(default, null): Int; public function new() { }}

So, unlike specifying the setter as 'never' (more on that below), 'null' only restricts access from outside the class definition scope, i.e. all scopes eligible for "public" access only. If you need strictly read-only properties, regardless access context, use 'never'.

11. 5. Never Property

This property non-access specifier can be useful in a number of cases. Below is an example where the number of stored List items is returned by the numItems property. Of course, the return value should always be read from the List and never be set explicitly..

haXe2

42

Page 43: haXe 2 Language Reference

class Container {

private var items : List<Item>; public var numItems( getNumItems, never ) : Int; function getNumItems() : Int { return items.length; }

public function new() { items = new List(); items.add( new Item() ); items.add( new Item() ); }}

Now, if called after adding the items in the constructor, both numItems = 3; and Reflect.setField(this, "numItems", 3); would fail because of the never access specified. On the other hand, if null was specified instead of never, the compiler would have allowed the Reflect call. This could mislead the developer into property abuse.

haXe2

43

Page 44: haXe 2 Language Reference

12. Optional ArgumentsSome function parameters can be made optional by using a question mark ? before the parameter name :

class Test { static function foo( x : Int, ?y : Int ) { trace(x+","+y); } static function main() { foo(1,2); // trace 1,2 foo(3); // trace 3,null }}

12.1. Default values

When not specified, an optional parameter will have the default value null. It's also possible to define another default value, by using the following syntax :

static function foo( x : Int, ?y : Int = 5 ) { // ... }

Thanks to type inference, you can also shorten the syntax to the following :

static function foo( x : Int, y = 5 ) { // ... }

12.2. Ordering

Although it is advised to put optional parameters at the end of the function parameters, you can use them in the beginning or in the middle also.

Also, optional parameters are independent in haXe. It means that one optional parameter can be used without providing a previous one :

function foo( ?x : A, ?y : B ) { }

foo(new A()); // same as foo(new A(),null); foo(new B()); // same as foo(null, new B()); foo(); // same as foo(null,null); foo(new C()); // compile-time error foo(new B(),new A()); // error : the order must be preserved

However, such usages of optional arguments could be considered quite advanced.

haXe2

44

Page 45: haXe 2 Language Reference

12.3. Enum Values

Enums' values can not be used as default values for optional arguments. See Enums for more information.

12.4. Warning

Optional Arguments are a compile-time feature and therefore their behavior may vary on different platforms when used on Dynamic calls or with Reflection.

haXe2

45

Page 46: haXe 2 Language Reference

13. Conditional CompilationSometimes you might want to have a single library using specific API depending on the platform it is compiled on. At some other time, you might want to do some optimizations only if you turn a flag ON. For all that, you can use conditional compilation macros (AKA preprocessor macros):

Here's an example of multiplaform code:

#if flash8 // haXe code specific for flash player 8 #elseif flash // haXe code specific for flash platform (any version) #elseif js // haXe code specific for javascript plaform #elseif neko // haXe code specific for neko plaform #else // do something else #error // will display an error "Not implemented on this platform" #end

There is also a not prefix, which is the exclamation mark. So for a block that is compiled for every plaform except for PHP, you can do:

#if !php // This code is not for PHP! #end

In addition to the various platform defines, you can also detect if this is a debug-enabled build (set using -debug):

#if debug trace("Debug infos for all debug compiles"); #end

You can define your own variables by using the haXe compiler commandline options (for example using -D mydebug):

#if mydebug trace("Some personalized debug infos"); #end

Logical and/or operators are also supported:

#if (neko && mydebug) // Only for "mydebug" mode on Neko #end

#if (flash || php) // Code that works for either flash or PHP #end

haXe2

46

Page 47: haXe 2 Language Reference

14. InlineThe inline keyword can be used in two ways: for static variables and for any kind of method.

14.1. Inlining Static Variables

For static variables, it's pretty simple. Every time the variable is used, its value will be used instead of the variable access. Example :

class Test { static inline var WIDTH = 500; static function main() { trace(WIDTH); }}

Using "inline" adds a few restrictions :

1 the variable must be initialized when declared

2 the variable value cannot be modified

The main advantage of using "inline" is that you can use as many variables as you want without slowing down your code with these variables accesses since the value is directly replaced in the compiled/generated code.

14.2. Inlining Methods

The principle is the same for a method. The less expensive function call is the one that is never done. In order to achieve that for small methods that are often called, you can "inline" the method body a the place the method is called.

Let's have a look at one example :

class Point { public var x : Float; public var y : Float; public function new(x,y) { this.x = x; this.y = y; } public inline function add(x2,y2) { return new Point(x+x2,y+y2); }}

class Main { static function main() { var p = new Point(1,2); var p2 = p.add(2,3); // is the same as writing : var p2 = new Point(p.x+2,p.y+3); }}

Again, there's some limitations to inline functions :

haXe2

47

Page 48: haXe 2 Language Reference

1 they cannot be redefined at runtime

2 they cannot be overridden in subclasses

3 an function containing "super" accesses or declare another function cannot be inlined

4 if the inline function has arguments, then the arguments evaluation order is undefined and some arguments might even be not evaluated, which is good unless they have some expected side-effects

5 if the inline returns a value, then only "final returns" are accepted, for example :inline function foo(flag) { return flag?0:1; } // acceptedinline function bar(flag) { if( flag ) return 0; else return 1; } // acceptedinline function baz(flag) { if( flag ) return 0; return 1; } // refused

Apart from these few restrictions, using inline increases the compiled/generated codesize but brings a lot of additional speed for small methods. Please note that it's also possible to inline static methods.

haXe2

48

Page 49: haXe 2 Language Reference

15. Keywords1 break

Exit a loop immediately.

2 callbackCurries a function call. Useful for passing functions.

3 caseSpecifies an entry in a switch statement.

4 castAttempt to get a value as a different type. Can also be used to indicate that a class' field can be dynamically overridden.

5 catchDeclares code that is called when an exception occurs.

6 classDeclares a class.

7 continueSkip to the next loop iteration.

8 defaultIf used in a switch statement, default is used to indicate a case that will be executed if none of the other cases were executed. If used in a property definition, default indicates that the classic field access are available.

9 doDeclares a "do-while" loop.do expr-loop while( expr-cond );

10 dynamicUsed in a property definition to indicate that access will be set at runtime. Also used as a flag in a class variable or method declaration to indicate that the field may be dynamically rebound.

11 elseDeclares a block to be executed if the condition is not true.if( expr-cond ) expr-1 [else expr-2]

12 enumDeclares an enum.

haXe2

49

Page 50: haXe 2 Language Reference

13 extendsDeclares a class to be a subclass of another class.

14 externIndicates that the class is already defined.

15 falseA boolean value that evaluates to false.

16 forDeclares a "for" loop.for( variable in iterable ) expr-loop;

17 functionDeclares a local function or method of a class.

18 hereExpands to a haxe.PosInfos structure.

19 ifDeclares a block to be executed if a condition is true.if( expr-cond ) expr-1 [else expr-2]

20 implementsDeclares the interfaces implemented by a class.

21 importIndicates that the class references a class from a different package is reference from the file.

22 inPart of the syntax of the "for" loop.

23 inlineIndicates that the compiler can speed up the code by replacing references to a function or static variable with the method body or variable's value, respectively.

24 interfaceDeclares an interface.

25 neverUsed in a property definition to indicate that access is not available.

26 newCreates an object by calling a class' constructor.

haXe2

50

Page 51: haXe 2 Language Reference

27 nullIf used in a comparison or assignment, null is variable without a value. If used in a property definition, null indicates that access is only allowed from within the class.

28 overrideIndicates that a class' field is overriding its parent class.

29 packagePackages can be used to group related classes.

30 privateIndicates that access to field is only allowed from the class.

31 publicIndicates that a field's access not restricted.

32 returnExit a function before the end or return a value from a function.

33 staticDeclares a class member.

34 superUsed by a class to call a method from its superclass.

35 switchEquivalent to multiple if...else if... tests on the same value.

36 thisUsed by a class to refer to the current object.

37 throwThrows an exception.

38 traceA global function to ease debugging. Outputs the given variable as a String.trace("Will be shown when compiled for debugging");

39 trueA boolean value that evaluates to true.

40 tryA try block is code where exception handlers can be defined.

haXe2

51

Page 52: haXe 2 Language Reference

41 typedefGives a name to an anonymous type.

42 untypedPrevent type checking for a block of code.

43 usingAllows an static functions to be called as if they were an object's methods.

44 varDeclares a local or class variable.

45 whileDeclares a "while" loop.while( expr-cond ) expr-loop;

haXe2

52