sabato 25 febbraio 2017

PHP anonymous functions and closures: is it smart?

As many other modern lagnuages, PHP is evolving and allows the usage of so called "closures": the idea is to define a function on the fly and use it as an "handler". More than that, a closure is a special function closed on a context, in particular the context that defined itself.
This is very useful, because the function should reference variables that are going to be out of scope, in a certain way as if they have been hardcoded into the function definition itself.

PHP closures don't work really this way, and I don't get the point: a PHP anonymous function can reference instance variable (i.e., members of the class where the function is defined) but not scoped variables (e.g., a variable in the function that is defining the anonymous function). More in general, it seems to me that PHP anonymous functions can reference global variables, and this is true also for class members, but not outer scope variables.
In other words this is not going to work:

function foo( $param ){
  ...
  $closure = function( $event ){
   if ( $event == $param ) { ... }
 };
}

because the $param variable is not visible within the anonymous function.
Now, there's a solution as reported in the documentation : you can specify which variables of the outer scope the anonymous function is going to "use":

function foo( $param ){
   ...
   $closure = function( $event ) use ( $param ){
    if ( $event == $param ) { ... }
   };
}


Now PHP has the opportunity to see that $param is needed inside the anonymous function, that becomes a "real" closure.
This is just another feature I don't like in the PHP language: why is what every developer expects to be a closure not being such? Moreover the abuse of the word "use" (needed also for namespaces handling) produce an operator overload I don't like very much.
Last but not least, while I get the idea of forcing a developer to declare what he is going to use and do, why not simplifying his life declaring what is using as local (e.g., local in Perl)?

Nessun commento: