5.11 Local Functions

Haxe supports first-class functions and allows declaring local functions in expressions. The syntax follows class field methods:

class Main {
  static public function main() {
    var value = 1;
    function myLocalFunction(i) {
      return value + i;
    }
    trace(myLocalFunction(2)); // 3
  }
}

We declare myLocalFunction inside the block expression of the main class field. It takes one argument i and adds it to value, which is defined in the outside scope.

The scoping is equivalent to that of variables and for the most part writing a named local function can be considered equal to assigning an unnamed local function to a local variable:

var myLocalFunction = function(a) { }

However, there are some differences related to type parameters and the position of the function. We speak of a "lvalue" function if it is not assigned to anything upon its declaration, and an "rvalue" function otherwise.

  • Lvalue functions require a name and can have type parameters.
  • Rvalue functions may have a name, but cannot have type parameters.
since Haxe 4.0.0
Arrow functions

Haxe 4 introduced a shorter syntax for defining local functions without a name, very similar to the function type syntax. The argument list is defined between two parentheses, followed by an arrow ->, followed directly by the expression. An arrow function with a single argument does not require parentheses around the argument, and an arrow function with zero arguments should be declared with () -> ...:

class Main {
  static public function main() {
    var myConcat = (a:String, b:String) -> a + b;
    var myChar = (a:String, b:Int) -> (a.charAt(b) : String);
    $type(myConcat); // (a : String, b : String) -> String
    $type(myChar); // (a : String, b : Int) -> String
    trace(myConcat("foo", "bar")); // "foobar"
    trace(myChar("example", 1)); // "x"
    var oneArgument = number -> number + 1;
    var noArguments = () -> "foobar";
    var myContains = (a:String, needle:String) -> {
      if (a.indexOf(needle) == -1)
        return false;
      trace(a, needle);
      true;
    };
  }
}

Arrow functions are very similar to normal local functions, with a couple of differences:

  • The expression after the arrow is implicitly treated as the return value of the function. For simple functions like myConcat above, this can be a convenient way to shorten the code. Normal return expressions can still be used, as shown in myContains above.
  • There is no way to declare the return type, although you can use a type check to unify the function expression with the desired return type.
  • Metadata cannot be applied to the arguments of an arrow function.