Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:88579 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 14657 invoked from network); 30 Sep 2015 12:53:04 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 30 Sep 2015 12:53:04 -0000 Authentication-Results: pb1.pair.com smtp.mail=bobwei9@hotmail.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=bobwei9@hotmail.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain hotmail.com designates 65.55.111.109 as permitted sender) X-PHP-List-Original-Sender: bobwei9@hotmail.com X-Host-Fingerprint: 65.55.111.109 blu004-omc2s34.hotmail.com Received: from [65.55.111.109] ([65.55.111.109:54278] helo=BLU004-OMC2S34.hotmail.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id DC/10-13134-F2BDB065 for ; Wed, 30 Sep 2015 08:53:03 -0400 Received: from BLU436-SMTP125 ([65.55.111.72]) by BLU004-OMC2S34.hotmail.com over TLS secured channel with Microsoft SMTPSVC(7.5.7601.23008); Wed, 30 Sep 2015 05:53:00 -0700 X-TMN: [IKvqLUhtciTZ+YRCzutBk+uFid371xGB] X-Originating-Email: [bobwei9@hotmail.com] Message-ID: Content-Type: multipart/alternative; boundary="Apple-Mail=_D7A6B20D-7C23-4217-9137-2816B88F5CE3" MIME-Version: 1.0 (Mac OS X Mail 8.2 \(2070.6\)) In-Reply-To: Date: Wed, 30 Sep 2015 14:52:56 +0200 CC: internals References: To: Levi Morrison X-Mailer: Apple Mail (2.2070.6) X-OriginalArrivalTime: 30 Sep 2015 12:52:58.0185 (UTC) FILETIME=[EEA2EB90:01D0FB7E] Subject: Re: [PHP-DEV] Arrow function expressions in PHP From: bobwei9@hotmail.com (Bob Weinand) --Apple-Mail=_D7A6B20D-7C23-4217-9137-2816B88F5CE3 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" > Am 26.9.2015 um 18:17 schrieb Levi Morrison : >=20 > (Email in gist format: > https://gist.github.com/morrisonlevi/fa7984c04ff176b5a87c) >=20 > In EcmaScript 2015 (ES6) the expression `(x) =3D> x * 2` means to = create > an anonymous function with one parameter `x` that will return `x * 2`. > For example: >=20 > (x) =3D> x * 2 > // is equivalent to: > function(x) { return x * 2; } >=20 > A modified example from [documentation by Mozilla Developer > Network][1] page demonstrates how they are useful: >=20 > var a =3D [ > "Hydrogen", > "Helium", > "Lithium", > "Beryl=C2=ADlium" > ]; >=20 > var a2 =3D a.map(function(s){ return s.length }); // pre-ES6 >=20 > var a3 =3D a.map((s) =3D> s.length); // ES6 >=20 > 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: >=20 > // 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) =3D> $x * 2] >=20 > // 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) =3D> $x * 2; >=20 > This is why Bob Weinand [proposed][2] using `~>` instead of `=3D>`. > However, if we allow type declarations there is another issue. In the > definition `(Type &$x) =3D> expr` the `(Type &$var)` part can parse as > "take constant `Type` and variable `$var` and do a bitwise and `&` > operation." After that the `=3D>` 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 `=3D>` to `~>` doesn't affect this issue. >=20 > We could solve the first ambiguities with prefering the current > meaning with `key =3D> 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. >=20 > So how can we have shorter closures without this mess? One simple way > is to require the `function` prefix: >=20 > // clearly an array with an anonymous function > [function($x) =3D> $x * 2]; >=20 > // clearly yields an anonymous function > yield function($x) =3D> $x * 2; >=20 > // clearly an anonymous function > function(Type &$x) =3D> expr; >=20 > Requiring the `function` prefix mitigates one of the value parts of > arrow functions: they are short. >=20 > Another option would be to resolve the ambiguities with keys and > values but to change the type information in parameters: >=20 > (&$input: array) =3D> expr >=20 > 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) >=20 > I would prefer that we shorten the `function` keyword to `fn`: >=20 > fn($x) =3D> $x * 2 >=20 > 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`. >=20 > What concerns do you have about `fn($x) =3D> $x * 2` or `function($x) = =3D> > $x * 2`? I will be writing a proper RFC later but I wanted to get > discussion going now. >=20 > [1]: = https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Function= s/Arrow_functions > [2]: https://wiki.php.net/rfc/short_closures Hey, Thanks a lot for your thoughts on it. I think unlike a lot of critics in the original thread, this actually is = a viable solution. As I mentioned, I=E2=80=99d prefer fn($x) =3D> $x ** 2 as general short = Closure syntax (no alias to function), for better distinguishing from = the normal Closures. Alternatively, Objective-C has also an interesting syntax with a leading = ^ (instead of your function). But, as long as we want types etc, we definitely need a prefix (as long = as we don=E2=80=99t want ugly parser hacking) =E2=80=A6 And in general, = the prefix also provides better recognizability that it actually should = be a short Closure [Also a reason why I dislike reusing function as = prefix here]. May you please set up a formal RFC for that in the wiki so that I may = withdraw my current RFC in favor of yours, which, I think, honestly is a = superior solution as it addresses types and as said, might be easier to = recognize at a quick glance. [And also obsoletes a lot of complaints about the operator =E2=80=A6 = Seems more people than expected actually dislike ~> ...] Thanks, Bob= --Apple-Mail=_D7A6B20D-7C23-4217-9137-2816B88F5CE3--