Influence of fashion that Arrow functions in Javascript became, no doubt.
In short, the differences are:
- Syntactic difference (anonymous functions are syntactically different from new functions in arrow).
- Unlike anonymous functions, which accept statements and expressions (within a block (
{ ... }
), Arrow functions only have a single expression. A Arrow Function does not have a block, so it can only evaluate (and return) a single expression.
- Differences in scope (reading and modification of higher scope names behave differently).
Reading of variables of higher scope
As Arrow functions inherit all names from higher scopes automatically. In computer science, this behavior is called enclosure (of the English closure). As Arrow functions PHP implemented this system in a very similar way to closures javascript.
Just be careful not to confuse that name with the class Closure
, that PHP has had for some time!
Thus, with the Arrow functions you can use any kind of name of any parent scope without explicit indications. With the old anonymous functions, you should "declare" that you are using a higher scope variable using the directive use
.
See an example of code that uses anonymous function:
<?php
$exp = 3;
$nums = [1, 2, 3, 4, 5];
// Função anônima.
// Note que preciso declarar o uso de `$exp` explicitamente.
$result = array_map(function ($num) use ($exp) {
return pow($num, $exp);
}, $nums);
print_r($result); //=> [1, 8, 27, 64, 125]
In the example above, if the directive use ($exp)
had it not been used, such a variable would be undefined in the scope of the function. It would receive a warning such as:
PHP Warning: Undefined variable $exp in /Users/luiz/Dev/.Scripts/arrow-fn.php on line 9
This explicit use statement is not required in Arrow functions. Behold:
<?php
$exp = 3;
$nums = [1, 2, 3, 4, 5];
// Arrow function.
// Escopo léxico parente é "herdado":
$result = array_map(fn($num) => pow($num, $exp), $nums);
print_r($result); //=> [1, 8, 27, 64, 125]
I take the previous example to highlight the fact that Arrow functions can only return the result of the evaluation of a single expression. In the above example, the expression we return is the result of the application of the function pow
(potentiation).
Impossibility of modification of variables of higher scope
An external scope variable cannot be modified by a Arrow Function. If you try to make a modification, it will be ignored. See the example of the documentation[1]:
<?php
$x = 1;
$fn = fn() => $x++; // Não tem efeito
$fn();
print_r($x); //=> 1 (Não foi modificada!)
No doubt another example of the influence PHP is showing on functional programming, which preaches for the immutability of values. However, the question remains: does PHP really need to adhere to these principles?
Related: Every anonymous function is a closure ?
– Wallace Maxters