Lambdas: Introduction
Hack supports the creation of closures through a construct called lambda. Lambdas are generally less verbose than PHP closures and are often used in conjunction with functions like array_filter() or array_map().
Syntax
A lambda is introduced by the lambda operator ==>. To the left of ==> is the list of arguments to the closure. To the right, is an expression or list of statements enclosed by braces {}. See lambda design for more information.
Difference From Traditional Closures
This example shows you how to make use of the shorter lambda syntax. It also uses a Vector, which is one of Hack's collection classes.
<?hh
namespace Hack\UserDocumentation\Lambdas\Examples\Examples\Introduction;
function addLastname(): Vector<string> {
$people = Vector {
"Carlton",
"Will",
"Phil"
};
return $people->map($name ==> $name . " Banks");
}
function run(): void {
var_dump(addLastname());
}
run();
object(HH\Vector)#3 (3) {
[0]=>
string(13) "Carlton Banks"
[1]=>
string(10) "Will Banks"
[2]=>
string(10) "Phil Banks"
}
The above example is equivalent to the example below using PHP's traditional syntax for anonymous functions. You should see that lambdas make the code more readable and shorter.
<?hh
namespace Hack\UserDocumentation\Lambdas\Examples\Examples\Difference;
function addLastnameTraditional(): array<string> {
$people = array(
"Carlton",
"Will",
"Phil"
);
return array_map(function ($name) {
return $name . " Banks";
}, $people);
}
function run(): void {
var_dump(addLastnameTraditional());
}
run();
array(3) {
[0]=>
string(13) "Carlton Banks"
[1]=>
string(10) "Will Banks"
[2]=>
string(10) "Phil Banks"
}
Essentially, the function ($name) and return from the traditional closure was replaced with the much shorter $name ==>.
Capturing variables
PHP provides the keyword use to capture variables from the enclosing scope. Hack's lambdas make this even easier. You can use variables implicitly inside of a lambda.
<?hh
namespace Hack\UserDocumentation\Lambdas\Examples\Examples\CaptureVariables;
function addLastname(string $lastname): Vector<string> {
$people = Vector {
"Carlton",
"Will",
"Phil"
};
return $people->map($name ==> $name . " " . $lastname);
}
function addLastnameTraditional(string $lastname): array<string> {
$people = array(
"Carlton",
"Will",
"Phil"
);
return array_map(function ($name) use ($lastname) {
return $name . " " . $lastname;
}, $people);
}
function run(): void {
var_dump(addLastnameTraditional("Smith"));
var_dump(addLastname("Smith"));
}
run();
array(3) {
[0]=>
string(13) "Carlton Smith"
[1]=>
string(10) "Will Smith"
[2]=>
string(10) "Phil Smith"
}
object(HH\Vector)#8 (3) {
[0]=>
string(13) "Carlton Smith"
[1]=>
string(10) "Will Smith"
[2]=>
string(10) "Phil Smith"
}
Notice in addLastName() we are using the passed in parameter $lastname directly within the lambda whereas in addLastNameTraditional, the parameter $lastName must be explicitly captured and called out in a use.
NOTE: All captured variables are captured by value; capturing by reference is not supported. If you need to capture by reference, use a full PHP closure.