On Wed, 28 Apr 2021 at 15:31, Nikita Popov <nikita....@gmail.com> wrote:
> On Wed, Mar 24, 2021 at 5:20 PM Larry Garfield <la...@garfieldtech.com> > wrote: > > > Greetings, Internalians. > > > > Some months back I proposed an RFC for short functions. > > > > https://wiki.php.net/rfc/short-functions > > > > After some discussion, I put it on hold to ensure that it was compatible > > with the other discussion floating about around an alternate syntax for > > multi-line closures that did auto-capture. It's important that the > syntax > > of both proposals is consistent. > > > > Nuno Maduro and i have talked recently and worked out the syntax that is > > consistent between both proposals. That takes 'fn' off the table for > > short-functions, for reasons discussed in both RFCs. > > > > To that end, I offer: > > > > 1) The updated short-functions RFC: > > https://wiki.php.net/rfc/short-functions > > > > 2) A new RFC, code by Nuno, for auto-capturing multi-statement closures: > > https://wiki.php.net/rfc/auto-capture-closure > > > > These are separate RFCs and at this time we plan to send them to separate > > votes, but I list them together to demonstrate that they have been > > developed in a mutually-compatible way. > > > > Further details in the auto-capture-closure RFC. > > > > Hey Larry, > > I'm generally in favor of supporting auto-capture for multi-line closures. > I think that extensive experience in other programming languages has shown > that auto-capture does not hinder readability of code, and I don't see any > particular reason why the effects in PHP would be different. I also think > there is value in having a consistent syntax for closures -- currently, you > have two options, and may need to switch between them as you add or remove > code. > > There are some caveats though, which this RFC should address: > > 1. Auto-capture in arrow functions works by-value. This is sufficient for > the purpose of single-line arrow functions, where you would be hard-pressed > to perform any meaningful state mutation. For multi-line closures, it > becomes much more likely that you want to modify a value from the outer > scope. It should be possible to do this without switching to the function() > notation. > > I do believe that by-value capture is the correct default, and should > remain as such, but there should be an opt-in for by-reference capture. My > suggestion would be to allow use(&$count) on fn(), which allows capturing > certain variables by reference rather than by value. An alternative that > has previously been discussed is to allow changing the default capture mode > using something like use(&), but I believe it would be better if variables > captured by reference had to be spelled out explicitly. > > 2. For much the same reason, capture analysis for arrow functions is very > primitive. It basically finds all variables that are used inside the > closure body and tries to import them, silently failing if they are not > available in the outer scope. For multi-line closures, this would commonly > end up importing too many variables. For example: > > fn() { > $tmp = foo(); > bar($tmp); > return $tmp; > } > > Here, there is no need to import $tmp from the outer scope, but a naive > implementation (which I assume you're using) will still try to capture it. > Now, this has two effects: > > a) Performance, as we're trying to capture unnecessary variables. This may > be negligible, but it would be good to at least quantify. I would rather > there not be recommendations along the line of "you should use function() > for performance-critical code, because it's faster than fn()". > > b) Subtle side-effects, visible in debugging functionality, or through > destructor effects (the fact that a variable is captured may be > observable). I think it nothing else, the RFC should at least make clear > that this behavior is explicitly unspecified, and a future implementation > may no longer capture variables where any path from entry to read passes a > write. > > Regards, > Nikita > Hey Nikita, Concerning point 1: Agreed. Going to update both the pull request and the RFC accordingly. Concerning point 2: Developing some sort of static analysis that can infer what needs to be captured may be problematic. First, that won't be consistent with the way auto-capture currently works in PHP (one-line short closures). Second, what needs to be captured may be determined at runtime (thinking about eval, variables names computed at runtime, etc). Of course, I am willing to hear more thoughts on this. Regards, Nuno.