Re: Arrow function expressions in PHP

From: Date: Mon, 28 Sep 2015 21:38:19 +0000
Subject: Re: Arrow function expressions in PHP
References: 1  Groups: php.internals 
Request: Send a blank email to internals+get-88534@lists.php.net to get a copy of this message
On Sat, Sep 26, 2015 at 6:17 PM, Levi Morrison <levim@php.net> wrote: > (Email in gist format: > https://gist.github.com/morrisonlevi/fa7984c04ff176b5a87c) > > In EcmaScript 2015 (ES6) the expression (x) => x * 2 means > to create > an anonymous function with one parameter x that will return > x * 2. > For example: > > (x) => x * 2 > // is equivalent to: > function(x) { return x * 2; } > > A modified example from [documentation by Mozilla Developer > Network][1] page demonstrates how they are useful: > > var a = [ > "Hydrogen", > "Helium", > "Lithium", > "Beryl­lium" > ]; > > var a2 = a.map(function(s){ return s.length }); // pre-ES6 > > var a3 = a.map((s) => s.length); // ES6 > > There has been some talk about how we can use arrow function > expressions in PHP. In PHP using the same syntax would have some > ambiguities: > > // Does this mean: > // 1. Create an array key with the result of ($x) and a > value > with $x * 2 > // 2. Create an array with one value that is an anonymous function > [($x) => $x * 2] > > // Does this mean: > // 1. Yield a key with the result of ($x) and a value > with $x * 2 > // 2. Yield an anonymous function > yield ($x) => $x * 2; > > This is why Bob Weinand [proposed][2] using ~> instead of > =>. > However, if we allow type declarations there is another issue. In the > definition (Type &$x) => expr the (Type > &$var) part can parse as > "take constant Type and variable > $var and do a bitwise and & > operation." After that the => will be an unexpected > token. Even > though the rule would be invalid the parser doesn't know that far > ahead it will error and it doesn't know which rule to pick. Changing > the token from => to ~> > doesn't affect this issue. > > We could solve the first ambiguities with prefering the current > meaning with key => value and requiring the meaning with > closures to > wrap them in (). We could solve the latter ambiguity with a > backtracking parser since it will eventually error and then know to > pick the other rule. However, I really think this is a bad idea. > > So how can we have shorter closures without this mess? One simple way > is to require the function prefix: > > // clearly an array with an anonymous function > [function($x) => $x * 2]; > > // clearly yields an anonymous function > yield function($x) => $x * 2; > > // clearly an anonymous function > function(Type &$x) => expr; > > Requiring the function prefix mitigates one of the value parts > of > arrow functions: they are short. > > Another option would be to resolve the ambiguities with keys and > values but to change the type information in parameters: > > (&$input: array) => expr > > By putting the type after the variable (similar to how we declare > return types) we no longer have the issues with mis-parsing. Of > course, that's not how we declare parameter types currently. I think > we would need to permit it everywhere and deprecate the current syntax > with the type being prefixed. (By deprecate I mean in PHP 8 and not > remove it until PHP 9 or later) > > I would prefer that we shorten the function keyword to > fn: > > [fn($x) => $x * 2] > > This preserves the shortness of the expression while providing > unambiguous, simple parsing. Of course, now we have a similar issue: > we have both fn and function. > > What concerns do you have about fn($x) => $x * 2 or > `function($x) => > $x * 2`? I will be writing a proper RFC later but I wanted to get > discussion going now. > > [1]: > https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions > [2]: https://wiki.php.net/rfc/short_closures > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > Hello, personally, as a purely userland dev, I feel that the correct syntax would be the "simplest" one - and that's imho the (Type &$x) ==> expr Or the version with ~> operator - I don't care which one gets in, althought I would rather see the ==> one. :) I understand that there might be some ambiguity in the parser that would need to be solved by backtracking, but for using the language, the "simplest" option should IMHO be the correct one. Also not introducing any more "stuff" (like new parameter types syntax) would be a plus. For the need to have a single parameter enclosed with ( ) - by thinking more and more about it, I think that having the one special case for not requiring parenthesis around parameters is pretty uselss, since it would have to be there anyways if you wrote the typehint. PS: the [fn($x) => $x * 2] seems ambigous, from reader's POV; key of the item is result of fn($x) and value is $x * 2? Also, it would be a huge BC break with not allowing you to name functions fn(), wouldn't it? -- Regards Pavel Kouřil

« previous php.internals (#88534) next »