> On Jun 13, 2022, at 1:39 PM, Rowan Tommins <rowan.coll...@gmail.com> wrote:
> 
> On 13/06/2022 14:52, Larry Garfield wrote:
>>> That's one perspective. The other perspective is that the proposal is to
>>> extend closure syntax to support automatic capture.
>> As noted before, this is a distinction without a difference.
> 
> 
> It's a difference in focus which is very evident in some of the comments on 
> this thread. For instance, Arnaud assumed that adding "use(*)" would require 
> a change to arrow functions, whereas that never even occurred to me, because 
> we're looking at the feature through a different lens.
> 
> 
>>> By the way, the current RFC implies you could write this:
>>> 
>>> fn() use (&$myRef, $a) { $myRef = $a * $b; }
>> The RFC already covers that.  $b will be auto-captured by value from scope 
>> if it exists.  See the "Explicit capture" section and its example.
> 
> 
> So it does. I find that extremely confusing; I think it would be clearer to 
> error for that case, changing the proposal to:
> 
> > Short Closures support explicit by-reference capture with the |use| 
> > keyword. Combining a short closure with explicit by-value capture produces 
> > an error.
> 
> And the example to:
> 
> $a = 1;
> fn () use (&$b) {
>     return $a + $b; // $a is auto-captured by value
>                          // $b is explicitly captured by reference
> }
> 
> 
> Clearer syntax for this has been cited previously as an advantage of use(*) 
> or use(...):
> 
> $a = 1;
> function () use (&$b, ...) { // read as "use $b by reference, everything else 
> by value"
>     return $a + $b;
> }
> 
> 
>> 1. Auto-capture could still over-capture without people realizing it.  
>> Whether this is actually an issue in practice (or would be) is hard to say 
>> with certainty; I'm not sure if it's possible to make an educated guess 
>> based on a top-1000 analysis, so we're all trying to predict the future.
> 
> 
> I tried to make very explicit what I was and was not disputing:
> 
> > Whether the risk of these side effects is a big problem is up for debate, 
> > but it's wrong to suggest they don't exist.
> 
> The RFC seems to be implying that the implementation removes the side 
> effects, but it does not, it is users paying attention to their code which 
> will remove the side effects.
> 
> 
>> Arguably it's less of an issue only because short-closures are, well, short, 
>> so less likely to reuse variables unintentionally.
> 
> 
> Our current short closures aren't just a single *statement*, they're a single 
> *expression*, and that's a really significant difference, because it means to 
> all intents and purposes *they have no local scope*. (You can create and use 
> a local variable within one expression, but it requires the kind of twisted 
> code that only happens in code golf.)
> 
> If there are no local variables, there is nothing to be accidentally 
> captured. That's why the current implementation doesn't bother optimising 
> which variables it captures - it's pretty safe to assume that *all* variables 
> in the expression are either parameters or captured.
> 
> 
>> 2. The syntactic indicator that "auto capture will happen".  The RFC says 
>> "fn".  You're recommending "use(*)".  However, changing the indicator syntax 
>> would do nothing to improve point 1.
> 
> 
> The reason I think it would be better is because it is a more *intentional* 
> syntax: the author of the code is more likely to think "I'm using an 
> auto-capture closure, rather than an explicit-capture closure, what effect 
> will that have?" and readers of the code are more likely to think "hm, this 
> is using auto-capture, I wonder which variables are local, and which are 
> captured?"
> 
> Of course they can still guess wrong, but I don't think "fn" vs "function" is 
> a strong enough clue.

"Strong enough" is an opinion, and it seems all who have commented have 
differing ones of those.  

But maybe a memory device would help address (some of?) your concerns:

- fn() — It is SHORT and implicit. Short is CONVENIENT. Thus Short 
auto-captures variables because that is the most Convenient thing to do.

- function() — It is LONG. Long is more EXPLICIT. Thus Long requires Explicitly 
declaring variables, which is also more rigorous and robust.

Or for the TL;DR crowd:

- fn() => SHORT => CONVENIENT => Auto-captures
- function() => LONG => EXPLICIT => Requires declaration

Hope this helps. #fwiw

-Mike

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php

Reply via email to