Usage of function literals (lambda) functions in PHP 10-20-2013, 02:30 PM
#1
![[Image: LNly3cx.png]](http://i.imgur.com/LNly3cx.png)
![[Image: 7qBQKJ6.png]](http://i.imgur.com/7qBQKJ6.png)
In short, lambda functions (or function literals/function constants) are distinguishing from normal procedural functions with their ability to be created within other functions and used as valid syntax. They do not necessarily need to be defined beforehand and called correspondingly. As of version 5.3+ of PHP closures support is added. Let's take a few examples so as to make things clear.
PHP Code:
function & (arguments) use (variables) { code }
That's the syntax of a lambda function. Following that structure a basic example would look like so:
PHP Code:
$Antagonism = function () { echo "Infamous"; };
This particular example in which the function is appended to a variable has no actual implementation so let's take a look at another, more detailed example of what function literals represent. For the sake of this, let's create one multi-dimensional array which will store a small piece of information about a group of people with different ages.
PHP Code:
<?php
$Antagonism = array(
0=>array('name'=>'Divine', 'age'=>44),
1=>array('name'=>'Dyme', 'age'=>13),
2=>array('name'=>'HaxOr', 'age'=>19),
3=>array('name'=>'Pali', 'age'=>23),
4=>array('name'=>'Protagonist', 'age'=>31)
);
?>What we aim to do now is to sort those that are of legal age (18 or above) from those that are not of adult age yet. Now how are we used to do that with 'normal' functions (meaning without the usage of lambda functions)? Take the following piece of code for instance.
PHP Code:
<?php
$Antagonism = array(
0=>array('name'=>'Divine', 'age'=>44),
1=>array('name'=>'Dyme', 'age'=>13),
2=>array('name'=>'HaxOr', 'age'=>19),
3=>array('name'=>'Pali', 'age'=>23),
4=>array('name'=>'Protagonist', 'age'=>31)
);
function filter($members){
if(18<=$members['age']){
return $members;
}
}
$sort = array_filter($Antagonism, filter($members));
?>The array_filter() functions accepts two parameters. The first one is the array in which to search and the second argument is how the data should be filtered. Because we need everyone that is not only 18 but above, our second parameter also needs to be a function. This is how we would naturally apply a function within another but let's take an example of how this is being conducted with lambda functions.
Now the above example has the additional drawback that in order for us to or any third-party coder to grasp the idea of our function, he'll need to go upwards the source and find out the purpose of the function. In smaller projects that's okay but considering some 30k LOC repeating this process all the time, this means a total mess to both the author and any third-party inspection. Here is where function literals meddle:
PHP Code:
<?php
$Antagonism = array(
0=>array('name'=>'Divine', 'age'=>44),
1=>array('name'=>'Dyme', 'age'=>13),
2=>array('name'=>'HaxOr', 'age'=>19),
3=>array('name'=>'Pali', 'age'=>23),
4=>array('name'=>'Protagonist', 'age'=>31)
);
$sort = array_filter($Antagonism, function($members){
if(18<=$members['age']){
return $members;
}
});
?>Now let's dump the array and see what we've got so far:
PHP Code:
print_r($sort);
Obviously, the output would be the following:
Code:
Array ( [0] => Array ( [name] => Divine [age] => 44 )
[2] => Array ( [name] => HaxOr [age] => 19 )
[3] => Array ( [name] => Pali [age] => 23 )
[4] => Array ( [name] => Protagonist [age] => 31 ) )![[Image: WTBpMD4.png]](http://i.imgur.com/WTBpMD4.png)
One of the most common usages of implementation of lambda functions are in closures. The very idea of this derives from the fact that in most programming languages when an object is called and used, it's being destroyed for the rest of the execution of the code. With closures we can force that object to be existent after its initial usage as long as there is a reference to it and is not outside the scope of visibility. Now let's exemplify what we just mentioned. For the sake of this, we'll create two anonymous functions, one of which would be placed inside the other which will serve the role of our closure.
PHP Code:
<?php
$lambda = function($Keeper){
$closure = function($Antagonism) use ($Keeper){
return $Antagonism." at ".$Keeper
};
return $closure;
};
?>We'll take two more variables which will be appended the value of the lambda function with a desired parameter that we choose and visualize the output:
PHP Code:
<?php
$lambda = function($Keeper){
$closure = function($Antagonism) use ($Keeper){
return $Antagonism." at Antagonism ".$Keeper;
};
return $closure;
};
$closure1=$closure2=$lambda('is a professional');
echo $closure1('Keeper').'<br />';
echo $closure2('Dyme');
?>In both calls to the $lambda variable (which in our case is a function) both values have been saved since there has been a reference to both. Let's dump what we have so far:
PHP Code:
<?php
$lambda = function($Keeper){
$closure = function($Antagonism) use ($Keeper){
return $Antagonism." at Antagonism ".$Keeper;
};
return $closure;
};
print_r($closure1=$closure2=$lambda('is a professional'));
?>Code:
Closure Object ( [static] => Array ( [Keeper] => is a professional ) [parameter] => Array ( [$Antagonism] => ) )The interpreter recognizes the object as a closure within which there is one static array with a key of 'Keeper' and value of 'is a professional' and a parameter which is also an array but with an empty value for the key '$Antagonism'. Now let's take another variable which is external for the function and remove the external lambda function that we had before along with its calls and another closure which will be taking a parameter by reference.
PHP Code:
<?php
$Keeper = 7;
$closure = function() use ($Keeper){
return $Keeper = 10;
};
$closure1 = function() use (&$Keeper){
return $Keeper = 10;
};
echo $Keeper.'<br />';
$closure();
echo $Keeper.'<br />';
$closure1();
echo $Keeper;
?>Executing the above code, we aim to get the initial value of the variable $Keeper and visualizing it over and over again after each lambda function and its reference. This will result in the following:
Code:
7
7
10As we have declared the value of $Keeper as that of '7', it stays the same before it has been parsed through the function. After it has entered the first closure, it still remains '7' because the value of '10' refers only for the objects within the function and after the closure with the reference (&$), we end up with the new value.
![[Image: 4MR1niC.png]](http://i.imgur.com/4MR1niC.png)
I myself learnt this pretty recently and wanted to share it asap. Haven't really applied it any developments so far but I guess most of you will after you perceive its functionality and grasp the concept behind it.
This forum is dead



![[+]](https://sinister.li/images/modern/collapse_collapsed.png)