Search code examples
haxe

Optional argument not checked at compile time Haxe


I just discovered Haxe tonight and I am happily surprised how developer friendly the syntax is. Quickly understandable, a real joy that it is close to ECMAScript.

.
└── src/
    ├── http/
    │   ├── Router.hx
    │   └── Route.hx
    └── Main.hx

I have a Router class that declares a "addGetRoute" method, with an optional second parameter:

package http;

import http.Route;

class Router
{
    var routes: Array<Route>;

    public function new()
    {
        this.routes = [];   
    }

    public function addGetRoute(route: String, ?handler: () -> String): Void
    {
        this.routes.push(new Route(route, handler));
    }
}

This is the Route class content:

package http;

class Route
{
    var route: String;
    var handler: () -> String;

    public function new(route: String, handler: () -> String)
    {
        this.route = route;
        this.handler = handler;
    }
}

The thing that I don't understand, is that the compiler does not throws an error when seeing this code:

this.routes.push(new Route(route, handler));

I would expect it throws an error since the second parameter can be null.

Do I missed something?


Solution

  • By default, everything but basic types (Int, Float, Bool) are nullable in Haxe, including references to functions (and even basic types are nullable on dynamic targets). While adding ? to an argument does wrap the type in Null<T>, that doesn't have any effect if the type is already nullable. The primary reason to make an argument "optional" with ? is for it's implied = null default value, which allows skipping it at the call site.

    Since Haxe 4, there is actually an opt-in null safety feature, which enforces that only Null<T> is nullable and would thus give you the desired compiler error:

    @:nullSafety // opt-into null safety
    class Main {
        static function main() {
            new Route("example", null);
        }
    }
    

    source/Main.hx:4: characters 24-28 : Null safety: Cannot pass nullable value to not-nullable argument "handler" of function "new".

    However, do note that null safety is still considered experimental and you might run into some rough edges here and there.