Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:88588 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 60977 invoked from network); 1 Oct 2015 02:45:22 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 1 Oct 2015 02:45:22 -0000 Authentication-Results: pb1.pair.com header.from=bishop.bettini@gmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=bishop.bettini@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.212.171 as permitted sender) X-PHP-List-Original-Sender: bishop.bettini@gmail.com X-Host-Fingerprint: 209.85.212.171 mail-wi0-f171.google.com Received: from [209.85.212.171] ([209.85.212.171:37215] helo=mail-wi0-f171.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 24/52-38941-04E9C065 for ; Wed, 30 Sep 2015 22:45:21 -0400 Received: by wicfx3 with SMTP id fx3so8425878wic.0 for ; Wed, 30 Sep 2015 19:45:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:reply-to:sender:in-reply-to:references:date:message-id :subject:from:to:cc:content-type; bh=SfTCiojX+sAPzqHAwZsrpWbVG77f3ry18WF6H8Ib77I=; b=jzY6Q1QmkqqwpT2tsFA7kICmXgw4RyGb0S1VdyWoPgNvL+F6e5ciiiBqdXU68lDwtc 1WxRkS9Buerkp5dq+nWGcRr/frkEWZ/TO/VHuoDPr7UyNqSe5jUkxzWRmOt/DqeArXUu Y55G8h4Hh5aMTeV8iPZwUPZEBJyyIOrgF1qbrQ5voArZ1wjNl0wweAEyZXXUgat5efz1 RFP6Vlz+5Zid4Ee+Xkru3BNO5xm7RvMWVR2loUSDrwGE8B1UUCu6vd6QCOW7sMXf3PDV 2LJG2yyeSLwuQ0ovCMYHnnPq2a2xficdx9DfN4VVbndWGUGZf3dzb21zRDhcENp4mRZR 3rtw== MIME-Version: 1.0 X-Received: by 10.180.182.80 with SMTP id ec16mr527140wic.47.1443667517906; Wed, 30 Sep 2015 19:45:17 -0700 (PDT) Reply-To: bishop@php.net Sender: bishop.bettini@gmail.com Received: by 10.194.110.72 with HTTP; Wed, 30 Sep 2015 19:45:17 -0700 (PDT) In-Reply-To: <5606D0EB.3060106@gmail.com> References: <5606D0EB.3060106@gmail.com> Date: Wed, 30 Sep 2015 22:45:17 -0400 X-Google-Sender-Auth: 7WdCTwtSYGp78NUp-psaT6Zae_E Message-ID: To: Rowan Collins , Levi Morrison Cc: PHP internals Content-Type: multipart/alternative; boundary=047d7b6250b2942750052102091d Subject: Re: [PHP-DEV] Arrow function expressions in PHP From: bishop@php.net (Bishop Bettini) --047d7b6250b2942750052102091d Content-Type: text/plain; charset=UTF-8 On Sat, Sep 26, 2015 at 1:07 PM, Rowan Collins wrote: > On 26/09/2015 17:17, Levi Morrison wrote: > >> 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. >> > > If a keyword is required next to the parameters, having the => as a > separate token looks a bit weird. It no longer matches other languages, so > how about thinking a bit further outside the box? > > One of the random thoughts that popped into my head during the previous > discussion was to base the syntax on the C for-loop, which would also give > a place for bound variables without the "use" keyword. e.g. your example > could become fn($x;; $x * 2) > > I picked "lambda" as the keyword before, and gave these examples: > > # lambda(params; bound vars; expression) > $double = lambda($a;; 2*$a) > $x=3; $triple = lambda($a; $x; $x * $a) > > function sumEventScores($events, $scores) { > $types = array_map(lambda($event;; $event['type']), $events); > return array_reduce($types, lambda($sum, $type; $scores; $sum + > $scores[$type])); > } > > > Adding in the type information, we'd get this: > > lambda(int $sum, string $type; $scores; $sum + $scores[$type]) > # or with fn() if you prefer: > fn(int $sum, string $type; $scores; $sum + $scores[$type]) > > > If return typehints are also required, I'm not sure where they'd best be > placed. If they're outside the parens, they end up after the expression, > which might look odd: > fn(int $sum, string $type; $scores; $sum + $scores[$type]): int > > A few other possibilities: > fn(int $sum, string $type; $scores; $sum + $scores[$type]; int) > fn(int $sum, string $type: int; $scores; $sum + $scores[$type]) > fn:int(int $sum, string $type; $scores; $sum + $scores[$type]) > > > All of this assumes that the shorthand is only available for simple > expressions, not function bodies, but it seems a bit rendundant to allow > both of these: > function($x) { foo(); bar(); baz(); } > fn($x) => { foo(); bar(); baz(); } > > And only marginally more useful if variables are auto-captured, with all > the downsides of that which have already been raised: > function($x) use ($y) { foo($x); bar($x, $y); } > fn($x) => { foo($x); bar($x, $y); } I'm leaning toward a compromise between Levi's suggested syntax (which is unambiguous and short, but auto-closes over parent's scope) and Rowan's for-loop style (which imports variables but the syntax feels cramped to me). Example: $a = 1; $b = fn($x; $a) => $x + $a; // note the semi-colon here, $a is explicitly imported $c = $b(1); // 2 All variables after the semi-colon are imported. The semi-colon and variable list is optional. This could be extended to function proper, coexisting with, or deprecating, the use syntax. Example: Before: function foo($x) use ($y) { ... } Becomes: function foo($x; $y) { ... } And I think it continues to work with STH: function bar(string $x, int $y; int $a):int { $b = strlen($x) + $y + $a; return fn(int $c; int $b):int => $b + $c; } $a = 5; bar('hello', 1)(2); // lucky number 13 bishop --047d7b6250b2942750052102091d--