Re: [RFC] Auto-capture multi-line closures and shortfunctions take 2

From: Date: Fri, 26 Mar 2021 16:11:38 +0000
Subject: Re: [RFC] Auto-capture multi-line closures and shortfunctions take 2
References: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17  Groups: php.internals 
Request: Send a blank email to internals+get-113802@lists.php.net to get a copy of this message
> On Mar 26, 2021, at 8:12 AM, Olle Härstedt <olleharstedt@gmail.com> wrote: > > 2021-03-26 3:38 GMT+01:00, Mike Schinkel <mike@newclarity.net>: >> >> >>> On Mar 25, 2021, at 4:09 PM, Olle Härstedt <olleharstedt@gmail.com> >>> wrote: >>> >>> 2021-03-25 17:49 GMT+01:00, Mike Schinkel <mike@newclarity.net>: >>>>> On Mar 25, 2021, at 11:22 AM, Olle Härstedt <olleharstedt@gmail.com> >>>>> wrote: >>>>> >>>>> 2021-03-25 16:02 GMT+01:00, Mike Schinkel <mike@newclarity.net>: >>>>>> >>>>>> >>>>>>> On Mar 25, 2021, at 10:41 AM, Rowan Tommins >>>>>>> <rowan.collins@gmail.com> >>>>>>> wrote: >>>>>>> >>>>>>> On 25/03/2021 12:31, Nuno Maduro wrote: >>>>>>> >>>>>>>> The reason why we believe the vast majority of PHP Developers are >>>>>>>> going >>>>>>>> to >>>>>>>> appreciate this RFC is because multi-line short closures (aka >>>>>>>> Auto-capturing multi-statement closures) *are more simple, shorter >>>>>>>> to >>>>>>>> write, and prettier to read *— and the community love these >>>>>>>> changes >>>>>>>> as >>>>>>>> proven on "property promotions", "one-line short >>>>>>>> closures", etc. >>>>>>> >>>>>>> >>>>>>> My main point was that the RFC needs to spell out this argument, >>>>>>> rather >>>>>>> than taking it for granted that everyone agrees on "those >>>>>>> situations >>>>>>> where >>>>>>> that is warranted". >>>>>>> >>>>>>> Most of the current text should be summarised in a "syntax >>>>>>> choices" >>>>>>> section somewhere near the end. I would like to see much more space >>>>>>> devoted to: >>>>>>> >>>>>>> * Why we need this feature. What has changed since it was left out of >>>>>>> the >>>>>>> arrow functions RFC? What problems is it addressing? Why do you think >>>>>>> it >>>>>>> is the best approach to those problems? >>>>>>> * The exact semantics proposed: How will the variables to be captured >>>>>>> be >>>>>>> determined? Will it distinguish variables which are written before >>>>>>> they're >>>>>>> read, and if so how is that defined? Can auto-capturing closures be >>>>>>> nested, i.e. will "fn() { return fn() { echo $a; } }" capture >>>>>>> $a from >>>>>>> the >>>>>>> outermost scope? And so on... >>>>>>> >>>>>>> >>>>>>>> Besides, one advantage of this RFC is that it is consistent with >>>>>>>> the >>>>>>>> current syntax of the language and with the short-functions RFC[2]. >>>>>>>> For >>>>>>>> example, by proposing that "fn" keyword indicates a >>>>>>>> function will >>>>>>>> auto-capture variables, by value. >>>>>>> >>>>>>> >>>>>>> While it's a cute rationalisation, there's no intuitive >>>>>>> reason why >>>>>>> "fn" >>>>>>> should have that meaning; we could pick any aspect of the current >>>>>>> arrow >>>>>>> function syntax and say "the 'fn' keyword means >>>>>>> that". >>>>>>> >>>>>>> >>>>>>> >>>>>>>> On the other hand "use (*)" has no usages / or current >>>>>>>> meaning in >>>>>>>> the >>>>>>>> language. >>>>>>> >>>>>>> >>>>>>> This is a straw man argument. I could equally say that "fn() { } >>>>>>> has >>>>>>> no >>>>>>> usages or current meaning in the language" - of course it >>>>>>> doesn't, we >>>>>>> haven't added it yet! >>>>>>> >>>>>>> The "function use() {}" part of "function use(*) >>>>>>> {}" has a >>>>>>> well-established meaning, and "*" to mean >>>>>>> "everything" is a notation >>>>>>> developers are likely to be very familiar with. >>>>>>> >>>>>>> The two disadvantages I see with using "fn" as proposed are: >>>>>>> >>>>>>> * Because it's shorter, people will decide it's the >>>>>>> "better" version, >>>>>>> when >>>>>>> they don't actually need any variable capture. An explicit syntax >>>>>>> like >>>>>>> "use(*)" instead makes this a deliberate choice. >>>>>> >>>>>> And yet adding " use (*)" makes the syntax longer, which goes >>>>>> against >>>>>> one >>>>>> of >>>>>> the goals many people have for it: to be shorter. >>>>> >>>>> I don't understand why this is a target in the first place. Shorter >>>>> does not mean more readable, and readable is more important than >>>>> writable. >>>> >>>> I agree that readable is more important than writable, but shorter also >>>> does >>>> not necessarily mean it is *less* readable, either. >>> >>> Sure. The brain removes noise and reads in "symbols" anyway (where >>> "fn" or "function" is a symbol of size 1). >> >> That is actually not exactly true, at least not in all cases. >> >> When "nction" combined with " use (.....)" adds to line length such >> that a >> developer must scroll horizontally to see all the text then it is not the >> same. >> >> And this is not a hypothetical for those of us who frequently use vertical >> split screen in our editors — I am constantly battling with lines that are >> too long. >> >> Also when longer lines cause code to wrap on GitHub or in blog posts or >> other places then it is not the same. >> >>> A more important aspect of readability is the cognitive load on >>> short-term memory, or how many "chunks" the programmer has to keep in >>> memory to understand a piece of code. In this case, I think >>> immutability and local scope helps a lot, of which PHP has neither. Or >>> maybe predictability of the scope? All language quirks hurt >>> readability. I never had a problem with scope in JS, despite it >>> lacking immutability and only recently got proper block scope. >> >> Given that the RFC prescribes by-value capture and not by-ref capture how it >> is really even a problem? Or are you arguing that you fear people will just >> write closures hundreds of lines long? >> >> Maybe PHP should deprecate functions longer than 50 or 100 lines? >> <rhetorical question> >> >>> Maybe more important than explicit/implicit capturing of scope is to >>> keep your functions short...? In our legacy code-base, we have functions >>> thousands of lines long. I can see auto-capturing being a problem >>> there, but that's because of the technical debt and not the feature >>> itself, I guess. Will our juniors realize that, tho? >> >> Now here is where I think the real problem is, the fact that other >> developers write functions thousands of lines long. >> >> But realistically, legacy code won't be affected as people are rarely if >> ever going to go back to your legacy code and convert a thousand line >> function into a closure with auto-capture. > > No, I'm more concerned that someone will add a closer at the *bottom* > of a long-ass function, capturing all variables, and then not have a > properly defined lifetime, causing a memory leak or "spooky action at > a distance" with object references. In other words, could it be a > foot-gun? Maybe far-fetched, I don't know. Unless I misunderstand the RFC, the closure would only auto-capture the variables that are specifically referenced inside the closure, so I don't see it capturing *all* variables unless the developer intended it to by referencing each one of them explicitly. And since the RFC captures the variables by-value I don't see how auto-capture would be any different than using "use (...)," even with objects. So if the developer intends to capture all variables and/or captures objects and either of those actions result in a memory leak I don't see how it could be the fault of auto-capture any more than with the current "function (...) use (...) {...}" syntax? So it seems it would be on the developer, not on the proposed syntax. Or am I missing something? -Mike

« previous php.internals (#113802) next »