HaXe2 Lang Ref Sep 24 2010

download HaXe2 Lang Ref Sep 24 2010

of 52

Transcript of HaXe2 Lang Ref Sep 24 2010

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    1/52

    haXe 2Language Reference

    (Last Updated: 24 Sep 2010)

    haXe2

    1

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    2/52

    Table of Contents

    1. Basic Types! 62. Syntax! 7

    2.1. Constants! 72.2. Operations! 72.3. Unary operations! 82.4. Parentheses

    !8

    2.5. Blocks! 82.6. Local Variables! 92.8. Field access! 102.9. Calls! 102.10. New! 102.11. Arrays! 102.12. If! 112.13. While! 112.14. For! 122.15. Return! 122.16. Break and Continue! 132.17. Exceptions! 132.18. Switch! 142.19. Local Functions! 142.20. Anonymous Objects! 15

    3. Type Inference! 163.1. Printing a Type! 163.2. Local variable inference! 16

    haXe2

    2

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    3/52

    3.3. Function types inference! 163.4. Inference and type parameters! 173.5. User Choice! 18

    4. Object Oriented Programming! 194.1. Classes! 194.2. Constructor! 204.3. Class Inheritance! 204.4. Extends! 204.5. Implements! 214.6. Interfaces! 214.7. Helper Classes! 21

    5. Type Parameters! 235.1. Constraint Parameters! 23

    6. Enums! 246.1. Constructors parameters! 246.2. Switch on Enum! 256.3. Switch with Constructor Parameters! 256.4. Enum Type Parameters! 266.5. Using Enums as default value for parameters! 26

    7. Packages and Imports! 277.1. Imports! 277.1.1. Applying additional static methods to class instances! 287.1.2. Importing a single type from a module! 287.1.3. Importing using wildcards ('*')! 297.2. Type Lookup! 297.3. Enum Constructors! 29

    8. Dynamic! 308.1. Parameterized Dynamic Variables! 31

    haXe2

    3

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    4/52

    8.2. Implementing Dynamic! 318.3. Type Casting! 328.4. Untyped! 328.5. Unsafe Cast! 32

    9. Advanced Types! 339.1. Anonymous! 339.2. Typedef! 339.2.1. As aliases! 349.2.2. Private members! 349.2.3. Private types! 359.2.4. Accessing Typedefs From Other Packages! 359.3. Functions! 359.4. Unknown! 369.5. Extensions! 36

    10. Iterators! 3810.1. Implementing Iterator! 3810.2. Iterable Objects! 39

    11. Properties! 4011.1. Sample! 4011.2. Important Remarks! 4111.3. Dynamic Property! 4111.4. Null Property! 4211. 5. Never Property! 42

    12. Optional Arguments! 4412.1. Default values! 4412.2. Ordering! 4412.3. Enum Values! 4512.4. Warning! 45

    haXe2

    4

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    5/52

    13. Conditional Compilation! 4614. Inline! 47

    14.1. Inlining Static Variables! 4714.2. Inlining Methods! 47

    15. Keywords! 49

    haXe2

    5

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    6/52

    1. Basic Types

    The haXe syntax is Java/ActionScript/C++ like.

    A source code file is composed of an optional package name followed by several importsand type declarations. By convention, package names are composed of severalidentifiers each of which start with a lowercase letter and are separated from oneanother 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. Hereare some of the basic types as declared in the standard library :

    enumVoid{ }

    classFloat{ }

    classIntextendsFloat{ }

    enumBool{true;false;

    }

    enumDynamic { }

    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'sstill a valid type that can be used.

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

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

    4 Bool is an enumeration, like Void, but it has two instances true and false. Asyou can see, even standard types can be defined easily using the haXe typesystem. 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 typeparameters later in this document.

    haXe2

    6

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    7/52

    2. Syntax

    In haXe, all expressions have the same level. It means that you can nest them togetherrecursively without any problem. For example : foo(if (x == 3) 5 else 8). Asthis 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; // Int0xFF00; // Int

    123.0; // Float.14179; // Float

    13e50; // Float-1e-99; // Float

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

    true; // Boolfalse; // Bool

    null; // Unknown

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

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

    2.2. Operations

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

    1 v = e : assign a value to an expression, returns e2 += -= *= /= %= &= |= ^= = >>>= : assign after performing the

    corresponding operation

    3 e1 || e2 : Ife1 is true then true else evaluate e2 . Both e1 and e2 must beBool.

    4 e1 && e2 : Ife1 is false then false else evaluate e2 . Both e1 and e2 mustbe Bool.

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

    6 == != > < >=

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    8/52

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

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

    10 e1 - e2 : perform subtraction between two Int or Float expressions. ReturnInt 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, theyfirst increment the corresponding variable and then return the incrementedvalue. When used after, they increment the variable but return the value it hadbefore 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 whenperforming operations. The type of( e ) is the same as e and they both evaluate tothe 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. Forexample :

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

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

    haXe2

    8

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    9/52

    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 novalue is given then the variable is null by default. If no type is given, then the variabletype 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 cannot be accessed outside the block in which they are declared.

    2.7. Identifiers

    When a variable identifier is found, it is resolvedusing 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 { staticvar x : Int; var x : Int;

    functionnew(){ { // 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

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    10/52

    // x at this point means the function parameter }

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

    class D { functionnew(){ // x means the x Axis } }

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

    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. Youcan 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 nameand can take parameters :

    a = newArray();s = newString("hello");

    2.11. Arrays

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

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

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

    haXe2

    10

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    11/52

    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 ofif expressions :

    if(life == 0) destroy(); if(flag)1else2;

    Here's the generic syntax ofif expressions :

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

    First expr-cond is evaluated. It must be of type Bool. Then iftrue then expr-1 isevaluated, 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 typeVoid. If there is an else, then expr-1 and expr-2 must be of the same type and thiswill be the type of the if expression :

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

    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 ofa Block) then both expr-1 and expr-2 can have different types and the if block typewill 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

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    12/52

    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 foriterators, which will be introduced later in this document. Here's an example of a forloop :

    for( i in0...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, youcan 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 avalue to be returned :

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

    haXe2

    12

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    13/52

    2.16. Break and Continue

    These two keywords are useful to exit early a for orwhile loop or to go to the nextiteration 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 itfrom any calling function on the stack :

    function foo(){ // ... thrownew 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 ofexceptions. They're tested in the order they're declared. Catching Dynamic will catchall 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

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    14/52

    2.18. Switch

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

    if( v == 0)

    e1 elseif( v == foo(1))

    e2 elseif( v == 65 || v == 90)

    e3 else

    e4;

    Will translate to the following switch :

    switch( v ){

    case0:e1;

    case foo(1):e2;

    case65, 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 bycomma(s).

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

    On someplatforms, switches on constant values (especially constant integers) might beoptimized for better speed.

    Switches can also be used on enums with a different semantic. It will be explained laterin 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

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    15/52

    Local functions can access their parameters, the current class statics and also the localvariables 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 thenneed 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 oftype inference, anonymous objects are also strictly typed.

    haXe2

    15

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    16/52

    3. Type Inference

    Type Inference means that the type information is not only checked in the program, it'salso carriedwhen typing, so it doesn't have to be resolved immediately. For example alocal 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 givenexpression. At compilation, the type operation will be removed and only the expressionwill 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 somedocumentation.

    3.2. Local variable inference

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

    var loc;type(loc); // print Unknownloc = "hello";type(loc); // print String

    3.3. Function types inference

    Declaring the type of parameter passed to a class method or local function is alsooptional. The first time the function is used, the type of the parameter will be set to thetype 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 wereverse the two calls to f, the value type is set to Float first. A second call using anInt does not fail since Int is a subtype ofFloat.

    haXe2

    16

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    17/52

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

    f(12.2); // Sets the parameter type to Floatf(134); // Success

    In this example the two calls are near each other so it's quite easy to understand andfix. In larger programs with more complex cases, fixing such compilation problems canbe tricky. The easiest solution is to explicitly set the type of the function. Then the callthat 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(p: Class): 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'

    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 variabledeclared without type - the type inferring does not occur at that point, because thecombination 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 beingan abstract, see "Type parameters" doc. page), to decide what type it returns. Whenpassed a Dynamic object however, it is clear that the type parameter 'T' makes nosense and is unknown. Type inferring is delayed until further, when a call to g that takesa Float is able to tell the compiler to specify type ofb as Float. Hence the first type

    haXe2

    17

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    18/52

    statement traces "Unknown" and the second - "Float". After the type is inferred, it isnaturally immutable.

    3.5. User Choice

    Using type inference is a choice. You can simply not type your variables and functions

    and let the compiler inferthe types for you, or you can type all of them in order to havemore control on the process. The best is maybe in the middle, by adding some typing inorder to improve code documentation and still be able to write quickly some functionswithout typing everything.

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

    haXe2

    18

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    19/52

    4. Object Oriented Programming

    4.1. Classes

    We will quickly introduce the structure of classes that you might already be familiarwith 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;

    staticvar name : String = "MyString";

    function foo() : Void{ }

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

    Variables and methods can have the followingflags :

    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, itmust 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 thatsubclass or extends it. This ensures that the class internal state is notaccessible.By default, all fields are private. This corresponds to the keyword protected inmost other languages such as Java, PHP

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

    haXe2

    19

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    20/52

    Non-static variables may not have an initial value. Static variables can have an initialvalue, 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 { publicvar x : Int; publicvar y : Int;

    publicfunctionnew(){ this.x = 0; this.y = 0; } }

    Constructor parametrization & overloading :

    publicfunctionnew( 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 aninstance oftype A, B or C is required. This means that every instance of D also has thetypes A , B and C.

    4.4. Extends

    When extending a class, your class inherits from allpublic andprivate non-static fields.You can then use them in your class as if they where declared here. You can alsooverride a method by redefining it with the same number of arguments and types as itssuperclass. Your class can not inherit static fields.

    haXe2

    20

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    21/52

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

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

    } }

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

    class B extends A { functionnew(){

    super(36,""); } }

    4.5. Implements

    When implementing a class or an interface, your class is requiredto implement all thefields declaredor inheritedby the class it implements, with the same type and name.However the field might already be inheritedfrom a superclass.

    4.6. Interfaces

    An Interface is an abstract type. It is declared using the interface keyword. Bydefault, all interface fields arepublic. 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, unlikeother 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 classbecomes available:

    haXe2

    21

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    22/52

    // 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 mostlanguages. Since helper class names do not correspond with their .hx file names, theycan be harder to find in source trees.

    HaXe lets you mark an internal helper class with theprivate keyword, in the same waythat fields are marked:

    // both definitions in Foo.hxclass Foo { ... }privateclass 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 definitionin 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

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    23/52

    5. Type Parameters

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

    classArray {

    functionnew(){ // ... }

    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 arenot accessible. However when you declare an array you need to specify its type :Array or Array for example. This will act the same as if you hadreplaced 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 asArray, List, and Tree. You can define your own parameterizedclasses with severaltype 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 defineseveral constraints on them in order to be able to use them in the class implementation.For example :

    class EvtQueue { var evt : T; // ...

    }

    In this class, although the field evt is a class paramater, the typer knows that it hasboth types Event and EventDispatcher so it can actually access it like if it wasimplementing both classes. Later, when an EvtQueue is created, the typer will checkthat the type parameter either extends or implements the two types Event andEventDispatcher. When multiple constraint parameters are defined for a single classparameter, as in the example above, they should be placed within parenthesis in orderto 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

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    24/52

    6. Enums

    Enums are different to classes and are declared with a finite number ofconstructors.Here's a small example:

    enum Color {red;green;blue;

    }

    class Colors { staticfunction toInt( c : Color ) : Int{ returnswitch( 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 arethe 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 ofColor2'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

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    25/52

    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 thenit will check that all an enum's constructors are used within the switch, and if not thecompiler will generate a warning. For example, consider the first Colorenum :

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

    This will cause a compile errorwarning 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. Thiscan be quite useful, as when you add new constructors to your enum, compiler errorswill alert you to areas in your program where the new constructor should be handled.

    6.3. Switch with Constructor Parameters

    Ifenum constructor have parameters, they must be listed as variable names in a switchcase. This way all the variables will be locally accessible in the case expression andcorrespond to the type of the enum constructor parameter. For example, using theColor3enum:

    class Colors { staticfunction toInt( c : Color3 ) : Int{ returnswitch( c ){ case red: 0xFF0000; case green: 0x00FF00; case blue: 0x0000FF; case grey(v): (v

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    26/52

    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 {empty;cons( item : T, next : Cell );

    }

    classList { var head : Cell;

    publicfunctionnew(){

    head = empty; }

    publicfunction add( item : T ){head = cons(item,head);

    }

    publicfunction length() : Int{ return cell_length(head); }

    privatefunction cell_length( c : Cell ) : Int{ returnswitch( 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 constantand therefore cannot be used as default value for a parameter. However there's a simplework-around :

    enum MyEnum{myFirstValue;mySecondValue;

    }

    haXe2

    26

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    27/52

    class Test { staticfunction withDefaultValuesOnParameters(?a : MyEnum)! { if(a == null)

    a = MyEnum.myFirstValue; } }

    7. Packages and Imports

    Each file can contain several classes, enums and imports. They are all part of thepackage declared at the beginning of the file. Ifpackage is not declared then the defaultempty package is used. Each type has then a path corresponding to thepackage namefollowed 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 severalclasses in the same file, but the type name must be unique in the whole application, soconflicts can appear if you're not using packages enough (this does not mean that youhave to use long packages names everywhere).

    When creating types using packages, you should create a nested folder/directorystructure matching the package name, and your files defining the type should becreated in the innermost folder/directory. The name of the file should generally matchthe type you are creating. For example, to create the types E and C, in the packagemy.pack as shown above, your folder structure should be my\pack and the files could beE.hxand C.hxin the folderpack. 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 alltypes, type names in packages must begin with an upper case letter. Hence My.Pack isan invalid package, as is my.Pack. Similarly, my.pack.e would not be a valid typename or import.

    7.1. Imports

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

    haXe2

    27

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    28/52

    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 weredeclared 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 fileas member functions on the type of their first parameter.Say we have:

    package my.pack; class StringUtils { publicfunction 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

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    29/52

    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 beimported, or you can use the full type path to access constructors as if they were staticfields 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 youcan use constructors directly without the need to import.

    haXe2

    29

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    30/52

    8. Dynamic

    Disclaimer: Dynamic variables are often necessary to ensure interoperability with thirdparty or platform dependent libraries, or for very specific cases where dynamic variablesare absolutely required. Their use is not encouraged for normal use, as their behaviordiffers between targets.

    When you want to get some dynamically typedbehavior and break free from the typesystem, you can use the Dynamic type which can be used in place ofanytype withoutany compile-time type-checking:

    var x : Dynamic = "";x = true;x = 1.744;x = {};x.foo = 'bar';

    x = newArray();

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

    At run time however, different targets may not recognize or even allow certainoperations on certain variables. For instance, on the flash9 (AVM2 target) a dynamicvariable 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 onNumber.

    //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 itselfimplements a Dynamic type), but modifying the fields of a flash9 Sprite class will causea run time reference error:

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

    s.foo = "Bar"; // ReferenceError!

    haXe2

    30

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    31/52

    In short, "Dynamic" variables never check for type by the compiler, whether they areassigned 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-timeerrors.

    An untypedvariable is of type Unknown and not Dynamic. That is, an untypedvariable

    does not have a type until it is determined by type inference. A Dynamic variable has aspecific type: an anytype.

    8.1. Parameterized Dynamic Variables

    Adding a parameter to a Dynamic type allows arbitrary access and assignment to anyfield as long as it is the same type as the parameter. For instance, Dynamicallows access or assignment to any field, as long as these accesses accept or produceString types. This is useful to encode Hashtables where items are accessed using dotsyntax:

    var att : Dynamic = xml.attributes;att.name = "Nicolas";att.age = "26";

    // ...

    or var foo : Dynamic = cast{};

    foo.name = "Nicolas";

    8.2. Implementing Dynamic

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

    class C implementsDynamic { publicvar name : String; publicvar 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

    Dynamic behavior is inherited by subclasses. When several classes are implementingdifferent 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 Dynamicthe function "resolve" will be called. This function is called with one parameter, theproperty attempted to be accessed, and can return any value.

    haXe2

    31

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    32/52

    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 ifa is an instance ofB or it will throwan exception "Class cast error".

    8.4. Untyped

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

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

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

    8.5. Unsafe Cast

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

    type.

    var y : B = cast0;

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

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

    haXe2

    32

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    33/52

    9. Advanced Types

    Up to now, we have seen the following types :

    1 class instance

    2 enum instance3 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 ofa Class identifier (corresponding to all the static fields) or an Enum identifier (listing allthe constructors). Here's an example that shows it:

    enum State {on;off;disable;

    }

    class C { staticvar x : Int; staticvar 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 togive a name to an anonymous type or a long type that you don't want to repeateverywhere in your program :

    typedef User = {

    var

    age : Int; var name : String;}

    // ....

    haXe2

    33

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    34/52

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

    // PointCube is a 3-dimensional array of points

    typedef PointCube = Array

    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 othertype 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, orwhatever.

    9.2.2. Private members

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

    class Foo { publicfunctionnew(){} publicfunction fullAccess()return true function restrictedAccess()return true}

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

    class Main { publicstaticfunction main() {

    var foo = new Foo();foo.fullAccess();

    //Compiler Error: Cannot access to private//field restrictedAccessfoo.restrictedAccess();

    var bar:Bar = foo;bar.fullAccess();

    //No Error, this is allowedbar.restrictedAccess();

    }}

    haXe2

    34

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    35/52

    9.2.3. Private types

    A type - class, typedef, interface or enum - can be defined as 'private', which willconfine its visibility only to the module it is defined in. Public types belong to packagesthey are defined in, and they can only be defined once. With private type definitionshowever 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 inanother module.

    privatetypedef 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 agiven typedef "MyType":

    // in Foo.hxprivatetypedef 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 toavoid 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 themby listing the arguments followed by the return type and separated with arrows. Forexample Int -> Void is the type of a function taking an Int as argument and returningVoid. Color -> Color ->Int takes two Color arguments and returns an Int.

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

    }

    function g(){

    haXe2

    35

    http://haxe.org/ref/type_advanced/oophttp://haxe.org/ref/type_advanced/oop
  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    36/52

    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 usedwith another type, it will change to it. This was explained in more details in typeinference. The id printed with the Unknown type is used to differentiate severalunknowns when printing a complex type.

    function f(){ var x;

    type(x); // print Unknownx = 0;

    type(x); // print Int }

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

    9.5. Extensions

    Extensions can be used to extend either a typedef representing an anonymous type or toextend 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'sunsafe so be careful :

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

    haXe2

    36

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    37/52

    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 compilerwill not be able to match this typedef against an anonymous object, or any otherinstanced class. This is because haXe is not fully structurally subtyped. Structuralsubtyping can only occur between anonymous typedefs or between an instance and ananonymous typedef.

    haXe2

    37

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    38/52

    10. Iterators

    An iterator is an object which follows the Iterator typedef (The type T is the iteratedtype) :

    typedefIterator = { function hasNext() : Bool; function next() : T; }

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

    for( i in0...10){ // ...

    }

    Or the usual for loop :

    for( i in0...arr.length ){foo(arr[i]);

    }

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

    10.1. Implementing Iterator

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

    classIntIter{ var min : Int; var max : Int;

    publicfunctionnew( min : Int, max : Int){ this.min = min; this.max = max; }

    publicfunction hasNext(){ return( min < max ); }

    publicfunction next(){ return min++;

    }

    }

    haXe2

    38

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    39/52

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

    var iter = newIntIter(0,10); for( i in iter ){

    // ... }

    The variable name in the for is automatically declared and its type is bound to theiterator 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 classdirectly in a for expression without the need to call the iterator() method:

    var a : Array = ["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 thesame as calling a.iterator() in the for expression.

    haXe2

    39

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    40/52

    11. Properties

    Properties are a specific way to declare class fields, and can be used to implementseveral kinds of features such as read-only/write-only fields or fields accessed throughgetter-setter methods.

    Here's a property declaration example :

    class C {

    publicvar 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/setter2 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 { publicvar ro(default,null) : Int; publicvar wo(null,default) : Int; publicvar x(getX,setX) : Int; publicvar y(getX,never) : Int; // here y should always equal x

    privatevar my_x : Int;

    privatefunction getX():Int{ return my_x; }

    privatefunction setX( v : Int):Int{ if( v >= 0)

    my_x = v; return my_x; }

    }

    haXe2

    40

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    41/52

    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 fieldwo 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 getXand 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 alwaystrace 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 ifthe type of the class is unknown.

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

    11.3. Dynamic Property

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

    class C { publicvar age(dynamic,dynamic) : Int; publicfunctionnew(){ }}

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

    haXe2

    41

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    42/52

    Reflect.setField(c,"get_age",function(){return my_age; }); Reflect.setField(c,"set_age",function(a){ my_age = a; returnmy_age; });

    trace(c.age); // 26c.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 theproperty, as is evidenced with the following example, which indeed succeeds to set thepropertys 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{

    staticpublicfunction set_prop_value(foo: Foo, value: Int)

    { /// Will actually set the value of 'prop' indeed.

    foo.prop = value;}

    publicvar prop(default, null): Int;publicfunctionnew(){}

    }

    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" accessonly. 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 anexample 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 setexplicitly..

    haXe2

    42

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    43/52

    class Container {

    privatevar items : List; publicvar numItems( getNumItems, never ) : Int; function getNumItems() : Int{ return items.length; }

    publicfunctionnew(){items = newList();items.add(new Item());items.add(new Item());

    }}

    Now, if called after adding the items in the constructor, both numItems = 3; andReflect.setField(this, "numItems", 3); would fail because of the neveraccess specified. On the other hand, ifnull was specified instead ofnever, thecompiler would have allowed the Reflect call. This could mislead the developer intoproperty abuse.

    haXe2

    43

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    44/52

    12. Optional Arguments

    Some function parameters can be made optional by using a question mark ? before theparameter name :

    class Test { staticfunction foo( x : Int, ?y : Int){trace(x+","+y);

    } staticfunction main(){

    foo(1,2); // trace 1,2foo(3); // trace 3,null

    }}

    12.1. Default values

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

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

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

    staticfunction 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 optionalparameter 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 errorfoo(new B(),new A()); // error : the order must be preserved

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

    haXe2

    44

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    45/52

    12.3. Enum Values

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

    12.4. Warning

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

    haXe2

    45

    http://haxe.org/ref/enumshttp://haxe.org/ref/enums
  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    46/52

    13. Conditional Compilation

    Sometimes you might want to have a single library using specific API depending on theplatform it is compiled on. At some other time, you might want to do someoptimizations only if you turn a flag ON. For all that, you can use conditionalcompilation 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 thisplatform"

    #end

    There is also a not prefix, which is the exclamation mark. So for a block that is compiledfor 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 debugtrace("Debug infos for all debug compiles");#end

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

    #if mydebugtrace("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

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    47/52

    14. Inline

    The inline keyword can be used in two ways: for static variables and for any kind ofmethod.

    14.1. Inlining Static Variables

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

    class Test { staticinlinevar WIDTH = 500; staticfunction 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 wantwithout slowing down your code with these variables accesses since the value is directlyreplaced 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 thatis 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 { publicvar x : Float; publicvar y : Float;

    publicfunctionnew(x,y){this.x = x; this.y = y; } publicinlinefunction add(x2,y2){returnnew Point(x+x2,y+y2); }}

    class Main { staticfunction 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

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    48/52

    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 beinlined

    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 unlessthey have some expected side-effects

    5 if the inline returns a value, then only "final returns" are accepted, for example :

    inlinefunction foo(flag){return flag?0:1; }// acceptedinlinefunction bar(flag){if( flag )return0; elsereturn1; }//acceptedinlinefunction baz(flag){if( flag )return0; return1; }// refused

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

    possible to inline static methods.

    haXe2

    48

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    49/52

    15. Keywords

    1 breakExit 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 aclass' 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 beexecuted if none of the other cases were executed. If used in a propertydefinition, default indicates that the classic field access are available.

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

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

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

    12enumDeclares an enum.

    haXe2

    49

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    50/52

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

    14externIndicates that the class is already defined.

    15falseA boolean value that evaluates to false.

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

    17functionDeclares a local function or method of a class.

    18hereExpands to a haxe.PosInfos structure.

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

    20implementsDeclares the interfaces implemented by a class.

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

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

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

    24interfaceDeclares an interface.

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

    26newCreates an object by calling a class' constructor.

    haXe2

    50

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    51/52

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

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

    29packagePackages can be used to group related classes.

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

    31publicIndicates that a field's access not restricted.

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

    33staticDeclares a class member.

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

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

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

    37throwThrows an exception.

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

    39trueA boolean value that evaluates to true.

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

    haXe2

    51

  • 8/3/2019 HaXe2 Lang Ref Sep 24 2010

    52/52

    41typedefGives a name to an anonymous type.

    42untypedPrevent type checking for a block of code.

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

    44varDeclares a local or class variable.

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

    haXe2