lambdaclosureshhvmlexical-scopehacklang

Change the value of a lexically scoped variable in a HHVM/Hack lambda expression?


Is it possible to change the value of a lexically scoped variable in a Hack lambda expression?

function allTrue(Map<string, bool> $map): bool {
    $valid = 1;
    $map->map($a ==> $valid &= $a);
    return $valid === 1;
}

$map = Map{'foo' => true, 'bar' => false };
var_dump(allTrue($map)); // true

I would expect the return value to be false


Solution

  • Unfortunately Hack lambda expressions do not support this. However you can still fall back on PHP 5.3 closure syntax.

    function allTrue(Map<string, bool> $map): bool {
        $valid = 1;
        $map->map(function ($a) use (&$valid) {
            $valid &= $a;
        });
        return $valid === 1;
    }
    
    $map = Map{'foo' => true, 'bar' => false };
    var_dump(allTrue($map)); // false 
    

    This works because: Objects of type Closure created by lambda expression syntax vs. PHP 5.3's closure syntax are interchangeable;

    From the docs

    Note:
    There are currently some limitations to lambda expressions that are being worked on or considered:

    Lambda expressions don't support capturing variables by reference. If the programmer wants to capture variables by reference, they must use PHP 5.3 closure syntax and put "&" in front of the variable in the "use(..)" list.

    Lambda expressions don't support returning by reference at present, but support could be added in the future.