2.1.5 Nullability

Define: nullable

A type in Haxe is considered nullable if null is a valid value for it.

It is common for programming languages to have a single, clean definition for nullability. However, Haxe has to find a compromise in this regard due to the nature of Haxe's target languages; while some of them allow and, in fact, default to null for anything, others do not even allow null for certain types. This necessitates the distinction between two types of target languages:

Define: Static target

Static targets employ their own type system where null is not a valid value for basic types. This is true for the Flash, C++, Java and C# targets.

Define: Dynamic target

Dynamic targets are more lenient with their types and allow null values for basic types. This applies to the JavaScript, PHP, Neko and Flash 6-8 targets.

There is nothing to worry about when working with null on dynamic targets; however, static ones may require some thought. For starters, basic types are initialized to their default values.

Define: Default values

Basic types have the following default values on static targets:

  • Int: 0
  • Float: NaN on Flash, 0.0 on other static targets
  • Bool: false

As a consequence, the Haxe Compiler does not allow the assignment of null to a basic type on static targets. In order to achieve this, the basic type has to be wrapped as Null<T>:

// error on static platforms
var a:Int = null;
var b:Null<Int> = null; // allowed

Similarly, basic types cannot be compared to null unless wrapped:

var a : Int = 0;
// error on static platforms
if( a == null ) { ... }
var b : Null<Int> = 0;
if( b != null ) { ... } // allowed

This restriction extends to all situations where unification is performed.

Define: Null<T>

On static targets the types Null<Int>, Null<Float> and Null<Bool> can be used to allow null as a value. On dynamic targets this has no effect. Null<T> can also be used with other types in order to document that null is a permitted value.

If a null value is "hidden" in Null<T> or Dynamic and assigned to a basic type, the default value is used:

var n : Null<Int> = null;
var a : Int = n;
trace(a); // 0 on static platforms