Re: [RFC] [VOTE] Short Closures
| From: | Tony Marston | Date: | Wed, 23 Sep 2015 09:25:39 +0000 |
| Subject: | Re: [RFC] [VOTE] Short Closures | ||
| References: | 1 2 3 4 5 6 7 8 9 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-88432@lists.php.net to get a copy of this message | ||
"Anthony Ferrara" wrote in message news:CAAyV7nHVNGG8yOyGhTE=pKACi4GDTgrdVcS4RDXb2fLmNy4Zpg@mail.gmail.com...
Dmitry, On Tue, Sep 22, 2015 at 3:19 PM, Dmitry Stogov <dmitry@zend.com> wrote:The more I read of this thread the more I think that it is a totally bad idea. If a single line of code requires a whole page to describe what it does, and even then there is a great deal of confusion between different people, then I would class that line of code as "unreadable". By this I mean that if I cannot determine within 5 seconds what a line of code does with complete accuracy then it becomes a maintenance nightmare. The objective of "good" programming is NOT to write code with as few keystrokes as possible, it is, as Abelson and Sussman wrote in 1944, "Programs must be written for people to read, and only incidentally for machines to execute". Martin Fowler, the author of Patterns of Enterprise Application Architecture, wrote "Any fool can write code that a computer can understand. Good programmers write code that humans can understand. " Please please please STOP with this nonsense about writing small amounts of clever code and stick with writing simple but readable code. I would much rather see 5 separate instructions on 5 separate lines than 5 instructions squeezed into a single line. IMHO the readability of a piece of code is directly proportional to the number of keystrokes used to write it. In other words, less keystrokes equals less readability. -- Tony MarstonOn Tue, Sep 22, 2015 at 9:20 PM, Anthony Ferrara <ircmaxell@gmail.com> wrote:On Tue, Sep 22, 2015 at 7:01 PM, Bob Weinand <bobwei9@hotmail.com> wrote:Dmitry, On Tue, Sep 22, 2015 at 2:05 PM, Dmitry Stogov <dmitry@zend.com> wrote:The current PHP version emits two warning on similar constructs, and this is explainable because we explicitly "use" $y. $ sapi/cli/php -r 'function foo(){(function($x) use ($y){$y=3; return $y+$x;})(5);return $y;} var_dump(foo());' PHP Notice: Undefined variable: y in Command line code on line 1 PHP Notice: Undefined variable: y in Command line code on line 1 NULLAm 22.09.2015 um 17:36 schrieb Dmitry Stogov <dmitry@zend.com>: On Tue, Sep 22, 2015 at 4:54 PM, Joe Watkins <pthreads@pthreads.org>wrote:It's clear to me that foo() will return NULL, but how many warnings about unused variable $y will we get? Thanks. Dmitry.butI'd really like to understand what you're trying to say there Dmitry,can'tI don't get it. What is your example function trying to show ? As it mentions in the RFC, vars in short closure are by-value, so Isee what side effects you might be thinking of ?butCheers Joe On Tue, Sep 22, 2015 at 9:25 AM, Dmitry Stogov <dmitry@zend.com> wrote:I'm against the magic - "automatically use () all of the (compiled) variables". I'm also against compound short closures with curly brackets. in my opinion they opens too many ambiguous questions. function foo() { (($x) ~> {$y = 3; return $y + $x;})(5); return $y; } also think about nested closures and use of variables from not direct enclosure. I'm not sure if we need all "functional programming" features in PHP,language.if we introduce them, lets do it consistently with the existinghinting.I think, this proposal can't be approved without support for typewrote:Thanks. Dmitry. On Tue, Sep 22, 2015 at 4:59 AM, Bob Weinand <bobwei9@hotmail.com>variableHey, Thanks for all your feedback in the discussion thread! So, before I start the vote, just two quick notes: I've added two notes about the statement syntax and the singleanyuse. Though a few people complained, I'm not switching to the ==> operator,asI noticed many people expected typehints to work (they don't due toparserlimitations) when they compared to Hack's short Closures. It alsoallows usto differ syntax-wise [e.g. for typehints] from Hack without causingtoconfusion later. Which should be the smartest choice: Avoid conflicts.(Ifanyone strongly feels against that, he may vote no, but I would likeactualnotbikeshed that in this Vote thread, but leave it free for eventualNotice: Undefined variable: y in php shell code on line 3 It just yields exactly one notice about the inexistent $y (as it obviously does not leak through the scope): by-value binding. I'm not sure what your issue here is?issues.) Now, the link to the RFC about Short Closures: https://wiki.php.net/rfc/short_closures or straight ahead to the vote: https://wiki.php.net/rfc/short_closures#vote Thanks, BobYes it can. Because the usages ofThere's an important distinction here. The explicitThis is not the way like PHP works and the proposed patch didn't change this. It produced warning on "implicit" use. Now Bob seems to fixed this by hiding the warning.use($y)triggers a notice because you said to use an undefined variable. function foo() { (($x) ~> {$y = 3; return $y + $x;})(5); return $y; } In this case, there's no practical binding of$yat all. The$yin the scope of the closure is never actually read from before it is assigned to. Meaning the variable doesn't need to exist prior to that assignment, meaning that it doesn't have to be bound (used), and as such shouldn't throw a notice.This becomes a ton easier if we ever move to an explicit CFG+SSA compile step. Then, we can see which variables dominate the closure to see what needs to be bound vs what doesn't. In this example, converted to SSA, you'd see: function foo() { $y1 = 12; (($x1) ~> {$y2 = 3; return $y2 + $x1;})(5); return $y1; } Hence you can see thatThis is interesting, and I also thought about this. But this is going to be different language with different rules. Also, this approach can't handle all possible cases in dynamic languages, where we can't say if variable is used or assigned first. function foo() { $y = 1; $f = ($x) ~> {$y2is truly an independent variable, and hence$y1never needs to be bound (and hence no notice). So your case of explicitly using$yisn't actually what's happening with the closure (at least with respect to userland behavior). Hence why the lack of notice exists. My $0.02 at least,for ($i = 0; $i < 2; $i++) { if ($x) { $y = 5; } else { echo $y }}; $f(0); $f(1); } Your approach won't be able to determine if $y in short closure is local variable or from function foo(). Anyway, this is not related to Bob's proposal.$yare not fully dominated by an assignment, there is at least one path from$y = 1toecho $ythat exists (this is trivial to prove). Hence the binding would need to happen (no matter if that path was chosen by the actual execution path). Variable-variables would need to be taken into account, but that would be easy to solve by saying if we see a Var-Var usage, bind everything unless we can prove the variable is dominated inside the lambda. And this is related to Bob's proposal in a way. Right now, he has to bind every symbol that exists in the closure using a non-notice read (if it exists in the parent, bind, otherwise don't notice). The point I was making is that if we modify our compiler it can get even smarter, reducing the cases where we over-bind (and thereby making it more efficient). Considering that some people are concerned around the performance implications of the binding, possible solutions to that problem do exist and could be implemented. Anthony