haXe

Type Inference

Type 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 immediatly. 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.

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.

Local variable inference

Type Inference enables the whole program to be strictly typed without any need to put types everywhere. In particular, local variables does 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

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.

    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

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.

«« Syntax - Object Oriented Programming »»

version #1108, modified 2008-05-03 10:40:16 by ponticelli