rfc:arrow_functions_v2
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision | ||
rfc:arrow_functions_v2 [2019/03/13 09:33] – nikic | rfc:arrow_functions_v2 [2019/04/17 10:51] – Start voting nikic | ||
---|---|---|---|
Line 4: | Line 4: | ||
* Author: Levi Morrison < | * Author: Levi Morrison < | ||
* Author: Bob Weinand < | * Author: Bob Weinand < | ||
- | * Target | + | * Target version: PHP 7.4 |
- | * Status: | + | * Implementation: |
+ | * Status: | ||
===== Introduction ===== | ===== Introduction ===== | ||
- | Anonymous functions | + | Anonymous functions |
- | Additionally, | + | Partly this is due to a large amount of syntactic boilerplate, |
- | single-expression closures. In practice these single-expression | + | import used variables. This makes code using simple |
proposes a more concise syntax for this pattern. | proposes a more concise syntax for this pattern. | ||
Line 22: | Line 23: | ||
</ | </ | ||
- | The closure performs a single operation | + | The actual |
- | other characters (excluding whitespace). This means that roughly 79% of the closure's code is | + | amidst |
- | overhead (30/38). For this RFC these extra characters are called ' | + | |
- | arrow functions to reduce | + | |
- | variables from the outer scope implicitly. Using arrow functions | + | |
- | to the following: | + | |
<PHP> | <PHP> | ||
Line 35: | Line 32: | ||
</ | </ | ||
- | This reduces | + | The question of short closures has been extensively discussed in the past. A previous |
- | + | [[rfc: | |
- | A previous [[rfc: | + | tries to address some of the raised concerns with a different choice of syntax that is not |
- | address some of the raised concerns with a different choice of syntax, that is not subject to the | + | subject to the limitations of the previous proposal. |
- | limitations of the previous proposal. | + | |
Additionally, | Additionally, | ||
binding semantics. Unfortunately short closures are a topic where we're unlikely to find a " | binding semantics. Unfortunately short closures are a topic where we're unlikely to find a " | ||
- | solution, due to significant constraints on the syntax and implementation. This proposal makes a | + | solution, due to significant constraints on the syntax and implementation. This proposal makes the |
choice that we consider "least bad". Short closures are critically overdue, and at some point we'll | choice that we consider "least bad". Short closures are critically overdue, and at some point we'll | ||
have to make a compromise here, rather than shelving the topic for another few years. | have to make a compromise here, rather than shelving the topic for another few years. | ||
Line 75: | Line 71: | ||
</ | </ | ||
- | Here the outer function captures '' | + | Here the outer function captures '' |
- | function. The overall effect is that the '' | + | function. The overall effect is that '' |
inner function. | inner function. | ||
Line 94: | Line 90: | ||
</ | </ | ||
- | ==== Static | + | ==== $this binding and static |
+ | |||
+ | Just like normal closures, the '' | ||
+ | |||
+ | < | ||
+ | class Test { | ||
+ | public function method() { | ||
+ | $fn = fn() => var_dump($this); | ||
+ | $fn(); // object(Test)# | ||
+ | |||
+ | $fn = static fn() => var_dump($this); | ||
+ | $fn(); // Error: Using $this when not in object context | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Static closures are rarely used: They' | ||
- | For the sake of completeness, | + | It has been suggested that we could use this opportunity to change |
- | < | + | |
- | bind the '' | + | |
- | is to avoid GC cycles and make destruction | + | |
==== By-value variable binding ==== | ==== By-value variable binding ==== | ||
Line 147: | Line 156: | ||
</ | </ | ||
- | Support for this could be easily | + | Support for this could be added by using a more general binding mechanism (bind everything |
- | rather than binding what is used) when variable variables are encountered. It's excluded here | + | rather than binding what is used) when variable variables are encountered. It's excluded here because |
- | because supporting this is a waste of opcodes, but if people don't like that, it can be supported. | + | it seems like an entirely unnecessary complication |
+ | people consider it necessary. | ||
==== Precedence ==== | ==== Precedence ==== | ||
Line 171: | Line 181: | ||
[[https:// | [[https:// | ||
information, | information, | ||
- | except one case where it is a namespace segment. | + | except one case where it is a namespace segment. |
+ | and I'm happy to rename it.) | ||
===== Examples ===== | ===== Examples ===== | ||
Line 212: | Line 223: | ||
<PHP> | <PHP> | ||
function complement(callable $f) { | function complement(callable $f) { | ||
- | return function (... $args) use ($f) { | + | return function (...$args) use ($f) { |
- | return !$f(... $args); | + | return !$f(...$args); |
}; | }; | ||
} | } | ||
Line 219: | Line 230: | ||
// with arrow function: | // with arrow function: | ||
function complement(callable $f) { | function complement(callable $f) { | ||
- | return fn(... $args) => !$f(... $args); | + | return fn(...$args) => !$f(...$args); |
} | } | ||
</ | </ | ||
Line 225: | Line 236: | ||
----- | ----- | ||
- | The following example was given to me by [[https:// | + | The following example was provided |
<PHP> | <PHP> | ||
Line 236: | Line 247: | ||
}, 0); | }, 0); | ||
- | echo $result; //6 | + | echo $result; // 6 |
// with arrow functions: | // with arrow functions: | ||
Line 243: | Line 254: | ||
-> | -> | ||
- | echo $result; //6 | + | echo $result; // 6 |
</ | </ | ||
===== Vote ===== | ===== Vote ===== | ||
- | Simple yes/no vote. | + | Voting started 2019-04-17 and ends 2019-05-01. A 2/3 majority is required. |
+ | |||
+ | <doodle title=" | ||
+ | * Yes | ||
+ | * No | ||
+ | </ | ||
===== Discussion ===== | ===== Discussion ===== | ||
Line 425: | Line 441: | ||
~($x) => $x * $y | ~($x) => $x * $y | ||
@($x) => $x * $y | @($x) => $x * $y | ||
+ | |||
+ | // Not possible, because _() is a valid function name, used as an alias for gettext() | ||
+ | _($x) => $x * $y | ||
</ | </ | ||
Line 447: | Line 466: | ||
It would be possible to resolve this ambiguity by lexing namespaced names as a single token | It would be possible to resolve this ambiguity by lexing namespaced names as a single token | ||
(removing support for whitespace inside them). This would, however, be a breaking change. | (removing support for whitespace inside them). This would, however, be a breaking change. | ||
+ | |||
+ | === Using -> and --> as arrows === | ||
+ | |||
+ | As an alternative to '' | ||
+ | |||
+ | <PHP> | ||
+ | ($x) -> $x | ||
+ | // already valid, more typically written as: | ||
+ | $x->{$x} | ||
+ | </ | ||
+ | |||
+ | '' | ||
+ | |||
+ | <PHP> | ||
+ | $x --> $x | ||
+ | // already valid, more typically written as: | ||
+ | $x-- > $x | ||
+ | </ | ||
+ | |||
+ | '' | ||
=== Different parameter list separators === | === Different parameter list separators === | ||
Line 517: | Line 556: | ||
into all the same parsing issues. | into all the same parsing issues. | ||
- | === Other ideas? | + | === Miscellaneous |
- | Happy to add more to this list. | + | It has been suggested |
+ | |||
+ | < | ||
+ | [\T &$x => $y] | ||
+ | // could be | ||
+ | [\(T &$x) => $y)] | ||
+ | // or | ||
+ | [(\T & $x) => $y] | ||
+ | </ | ||
==== Binding behavior ==== | ==== Binding behavior ==== | ||
Line 533: | Line 580: | ||
<PHP> | <PHP> | ||
$x = 1; | $x = 1; | ||
- | $fn = () => $x++; | + | $fn = fn() => $x++; |
$fn(); | $fn(); | ||
var_dump($x); | var_dump($x); | ||
Line 630: | Line 677: | ||
<PHP> | <PHP> | ||
+ | fn(params) => { | ||
+ | stmt1; | ||
+ | stmt2; | ||
+ | return expr; | ||
+ | } | ||
+ | // or possibly just | ||
fn(params) { | fn(params) { | ||
stmt1; | stmt1; | ||
Line 695: | Line 748: | ||
There are some possible variations of this, e.g. allow '' | There are some possible variations of this, e.g. allow '' | ||
+ | ===== Changelog ===== | ||
+ | |||
+ | * 2019-03-14: Clarify $this binding and explain why we're sticking with always-bind behavior. | ||
+ | * 2019-03-14: Mention '' |
rfc/arrow_functions_v2.txt · Last modified: 2020/08/01 23:53 by carusogabriel