====== PHP RFC: Alternative "use" syntax for Closures ======
* Version: 0.1
* Date: 2019-06-15
* Author: Wes (@WesNetmo)
* Status: Under Discussion
* First Published at: http://wiki.php.net/rfc/alternative-closure-use-syntax
===== Introduction =====
PHP users often say that they find defining the lexical-scope imports cumbersome, because
they hate importing the variables explicitly.
My opinion on the matter is that what's actually annoying is not writing the variable
names, but the syntax with which the imports are defined.
In ES we are required to declare variables but we don't find it annoying; in PHP we don't
have to declare variables, but we are required to specify which one we want to import in
''Closure''s. It won't be much different if not for the syntax. It is very standard in ES,
but irksome in PHP.
Specifically, it requires a lot of effort to write compared to normal expressions.
Whitespace, parentheses, possible indentation on different depths. Also, being in the
middle of the signature, it is very invasive, visually, as it separates the arguments from
the return information:
public function bar(){
// ...
$closure = function (
ArgumentType $argument1,
ArgumentType $argument2,
ArgumentType $argument3,
ArgumentType $argument4
) use ( // indent out
// indent in
$importVariable1,
&$importVariable2,
$importVariable3,
&$importVariable4
): ReturnType { // indent out again
// indent in again
};
}
// or also
public function bar(){
// ...
$closure = function (
ArgumentType $argument1,
ArgumentType $argument2,
ArgumentType $argument3,
ArgumentType $argument4
) use ( // indent out
// indent in
$importVariable1, &$importVariable2, $importVariable3, &$importVariable4
): ReturnType { // indent out again
// indent in again
};
}
===== Proposal =====
This RFC proposes to provide an alternative syntax for ''use()'', one resembling
''global'' or Python's ''nonlocal'' modifier:
$closure = function (
ArgumentType $argument1,
ArgumentType $argument2,
ArgumentType $argument3,
ArgumentType $argument4
): ReturnType {
use $importVariable1, &$importVariable2, $importVariable3, &$importVariable4;
// ...
};
// or also
$closure = function (
ArgumentType $argument1,
ArgumentType $argument2,
ArgumentType $argument3,
ArgumentType $argument4
): ReturnType {
use $importVariable1, &$importVariable2;
use $importVariable3, &$importVariable4;
// ...
};
Unlike ''global'', which is allowed everywhere in a function body, ''use'' must only
appear at the very top of the ''Closure'''s body. For example, the following code will
cause a syntax error:
$closure = function (
ArgumentType $argument1,
ArgumentType $argument2,
ArgumentType $argument3,
ArgumentType $argument4
): ReturnType {
use $importVariable1, &$importVariable2; // ok
echo 123;
use $importVariable3, &$importVariable4;
// ^ syntax error, as "use" can only be preceded by other "use" statements
};
Exactly like the current ''use()'', variables are imported by value, unless prefixed by
''&''. A ''Closure'' can define multiple ''use;'' statements; they can go on multiple
lines and they can be surrounded by whitespace and comments as with most of other
expression statements.
===== Backward Incompatible Changes =====
None.
===== Proposed PHP Version(s) =====
Next PHP minor version
===== Proposed Voting Choices =====
Vote will require 2/3 majority