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

2021-03-28 Thread Larry Garfield
On Sun, Mar 28, 2021, at 7:34 AM, Deleu wrote:
> >
> > but then we can bring up the side running RFC from
> > Larry which proposes to make the same short syntax available for other
> > function declarations, how would this work then with this mindset of
> > `fn` meaning auto capture? Does that mean a procedural function
> > declared with `fn` will now inherit the scope from which it was
> > declared (usually the global scope)? What about methods declarations,
> > do they import properties into the local scope? How does traits
> > interact here, same as methods?
> >
> 
> I think I remember the 1st version of Larry's RFC proposing `public fn
> classMethod(): bool => $this->myAttr;` as a class method which seems to
> match what you're trying to say here, but that has been withdrawn and the
> RFC no longer proposes the fn keyword for class methods or function
> declarations, which is discussed under *Background* of RFC
> https://wiki.php.net/rfc/auto-capture-closure. Larry and Nuno may correct
> me if I'm wrong but as far as I understood, that change happened to address
> exactly the points you're describing here: what does `public fn
> classMethod(): bool` would capture? There's actually little to no reason to
> do it. Larry's RFC still proposes a great improvement for
> getters/setters/short methods and Nuno's RFC allows us to write code that
> is naturally expected to work, such as `fn () => {...}`.
> 
> As for making `fn` an alias of `function` I believe that is already broken
> because of 7.4 arrow functions. As you describe, that would be "an
> exception" to PHP syntax, but more pressing it means that we would be
> wasting the potential of 2 separate keywords having different goals. I
> think it was Nikita that once said that we have a very limited budget on
> what we can do/offer through programming syntax and throwing `fn` out would
> be such a waste of that limited budget.
> 
> -- 
> Marco Aurélio Deleu

The short-functions RFC as initially proposed had two variants, one which just 
used =>, and one with used both => and fn.  Personally I don't have that strong 
of a feeling about function vs fn in that case.  However, when discussing with 
Nuno using "fn" to indicate auto-capture made the most sense, as => already 
very clearly means "evaluates to expression."

I'm personally not wedded to any specific syntax, as long as the net result is 
consistent and self-evident to both writers and readers, and allows for both 
auto-capturing lambdas and expression-style functions.

I'm not wild about function and fn being universally synonymous.  As Mike 
notes, it would create another coding style battlefront of when you should use 
one or the other since both are synonymous.  What we'd likely end up with is 
drifting toward the whole language using fn because it's easier to type, but 
not everyone, so you'd have a lot of inconsistency between projects.  If 
function and fn mean different things, there is no room for subjective 
preference.  You use the keyword that means the behavior you want.

As a thought experiment, let's play with the "auto" keyword for a moment.  (As 
I'm typing this I don't know what it will produce.)

$c = 1;

// Existing syntax.
$f = function($a, $b) use ($c) {
  return $a * $b * $c * $this->d;
};

// If you want to DISABLE object binding.
$d = $this->d;
$f = static function($a, $b) use ($c, $d) {
  return $a * $b * $c * $d;
};

// If you want to ENABLE auto-capture.
$f = auto function($a, $b) {
  return $a * $b * $c * $this->d;
};

// If you want to DISABLE object binding but ENABLE auto-capture.
$d = $this->d;
$f = static auto function($a, $b) {
  return $a * $b * $c * $d;
};

So we end up with one enable toggle and one disable toggle.  That's generally 
considered a bad idea.  It also means that what I believe is *usually* the most 
common desired configuration (don't capture $this, but capture anything else) 
the one that involves the most typing.

That doesn't seem ideal.

--Larry Garfield

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



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

2021-03-28 Thread Mike Schinkel



> On Mar 28, 2021, at 8:04 AM, Kalle Sommer Nielsen  wrote:
> 
> Den søn. 28. mar. 2021 kl. 14.30 skrev Deleu :
>> 
>> The fact that short closure is inconsistent with the rest of PHP is a done 
>> deal since the voting passed prior to 7.4 release. Unless there's a 
>> follow-up to deprecate the 7.4 short closure auto capture without `auto` 
>> keyword and make it look like PHP can't make up it's mind, I feel that your 
>> perspective doesn't match the proposed RFC. The RFC is extending short 
>> closure to support multiple statements and defining good semantics on how 
>> developers will interpret fn, => and {} throughout the language.
> 
> I think we have some sort of conundrum. I am not saying auto capture
> is not good semantics if that is what you are implying, I more than
> anyone would like consistency in the language but it is not a good
> language design to have two very similar features separated by a
> shorter keyword which implies totally different semantics. I don't
> find this a very intuitive way nor a good developer experience. I can
> understand that the connection of the `fn` keyword already having the
> meaning it has, but then we can bring up the side running RFC from
> Larry which proposes to make the same short syntax available for other
> function declarations, how would this work then with this mindset of
> `fn` meaning auto capture? Does that mean a procedural function
> declared with `fn` will now inherit the scope from which it was
> declared (usually the global scope)? What about methods declarations,
> do they import properties into the local scope? How does traits
> interact here, same as methods?
> 
> This is why I think having the `fn` being an alias of `function`
> neutralizes the argument of what happens for exactly those reasonings
> above, this allows arrow functions to continue being auto capture
> without any keyword.


I am curious how requiring developers to learn that "=>" means auto-capture and 
having developers question when they should choose "fn" instead of "function" 
when the answer is "it does not matter" is a more intuitive and a better 
developer experience than requiring developers to simply learn that "fn" means 
auto-capture?

-Mike

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



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

2021-03-28 Thread Deleu
>
> but then we can bring up the side running RFC from
> Larry which proposes to make the same short syntax available for other
> function declarations, how would this work then with this mindset of
> `fn` meaning auto capture? Does that mean a procedural function
> declared with `fn` will now inherit the scope from which it was
> declared (usually the global scope)? What about methods declarations,
> do they import properties into the local scope? How does traits
> interact here, same as methods?
>

I think I remember the 1st version of Larry's RFC proposing `public fn
classMethod(): bool => $this->myAttr;` as a class method which seems to
match what you're trying to say here, but that has been withdrawn and the
RFC no longer proposes the fn keyword for class methods or function
declarations, which is discussed under *Background* of RFC
https://wiki.php.net/rfc/auto-capture-closure. Larry and Nuno may correct
me if I'm wrong but as far as I understood, that change happened to address
exactly the points you're describing here: what does `public fn
classMethod(): bool` would capture? There's actually little to no reason to
do it. Larry's RFC still proposes a great improvement for
getters/setters/short methods and Nuno's RFC allows us to write code that
is naturally expected to work, such as `fn () => {...}`.

As for making `fn` an alias of `function` I believe that is already broken
because of 7.4 arrow functions. As you describe, that would be "an
exception" to PHP syntax, but more pressing it means that we would be
wasting the potential of 2 separate keywords having different goals. I
think it was Nikita that once said that we have a very limited budget on
what we can do/offer through programming syntax and throwing `fn` out would
be such a waste of that limited budget.

-- 
Marco Aurélio Deleu


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

2021-03-28 Thread Kalle Sommer Nielsen
Den søn. 28. mar. 2021 kl. 14.30 skrev Deleu :
>
> The fact that short closure is inconsistent with the rest of PHP is a done 
> deal since the voting passed prior to 7.4 release. Unless there's a follow-up 
> to deprecate the 7.4 short closure auto capture without `auto` keyword and 
> make it look like PHP can't make up it's mind, I feel that your perspective 
> doesn't match the proposed RFC. The RFC is extending short closure to support 
> multiple statements and defining good semantics on how developers will 
> interpret fn, => and {} throughout the language.

I think we have some sort of conundrum. I am not saying auto capture
is not good semantics if that is what you are implying, I more than
anyone would like consistency in the language but it is not a good
language design to have two very similar features separated by a
shorter keyword which implies totally different semantics. I don't
find this a very intuitive way nor a good developer experience. I can
understand that the connection of the `fn` keyword already having the
meaning it has, but then we can bring up the side running RFC from
Larry which proposes to make the same short syntax available for other
function declarations, how would this work then with this mindset of
`fn` meaning auto capture? Does that mean a procedural function
declared with `fn` will now inherit the scope from which it was
declared (usually the global scope)? What about methods declarations,
do they import properties into the local scope? How does traits
interact here, same as methods?

This is why I think having the `fn` being an alias of `function`
neutralizes the argument of what happens for exactly those reasonings
above, this allows arrow functions to continue being auto capture
without any keyword. And again; adding an `auto` keyword is also not
an alien thing to Closures because we already have the `static`
keyword which acts as a feature flag, something which arrow functions
already support which also is a case that can easily mess up the order
of which objects are destructed in if you make a Closure that does not
interact with `$this` from an object context without declaring it as
`static`.

While I did not agree with this in the initial RFC that implemented
arrow functions, I do see its value and agree with it due to the
narrow scope of which arrow functions have, and therefore I think it
is fine to have the exception of making arrow functions behave this
way and would have voted as such had it come to my desk today.

And again, kindly stop top posting.

-- 
regards,

Kalle Sommer Nielsen
ka...@php.net

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



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

2021-03-28 Thread Deleu
The fact that short closure is inconsistent with the rest of PHP is a done
deal since the voting passed prior to 7.4 release. Unless there's a
follow-up to deprecate the 7.4 short closure auto capture without `auto`
keyword and make it look like PHP can't make up it's mind, I feel that your
perspective doesn't match the proposed RFC. The RFC is extending short
closure to support multiple statements and defining good semantics on how
developers will interpret fn, => and {} throughout the language.

On Sun, Mar 28, 2021, 12:21 Kalle Sommer Nielsen  wrote:

> Den søn. 28. mar. 2021 kl. 13.02 skrev Deleu :
> >
> > This would lead to inconsistent behavior in the language when short
> closures auto capture without the auto keyword while multi statements
> closure doesn't.
> > One of the best features of these RFC are their cognitive definition
> that is clear, concise, consistent and simple.
>
> (First off, please read our mailing lists rules[1] and do not top post)
>
> If we go by the inconsistent behavior then by that definition short
> arrow functions are inconsistent with the rest of PHP as there is no
> auto capture elsewhere.
>
> This is not short arrow functions being expanded to support multi
> lines, but rather the other way around, with multi line closures being
> able to support auto capture which is identified by the `fn` keyword
> and because of that, I would much rather have a `fn` be an alias of
> `function` and then having the ability to put a keyword to declare
> that you wish to use auto capture (which is consistent with the
> exisiting design of PHP where you have to declare globals with the
> `global` keyword or explicit imports to closures with the `use`
> statement (which used to be done by the `lexical` keyword similarily
> to the `global` keyword in early PHP 5.3.0 development) -- if you are
> interested in this philosophy you can try lookup videos from some of
> Rasmus' presentations where he explains his dislike with globals
> coming from C). To back this up further, we also have the `static`
> keyword which acts as a feature flag so it is not unnatural, the
> naming of the keyword `auto` sure, but that is another discussion.
>
> [1]
> https://git.php.net/?p=php-src.git;a=blob_plain;f=docs/mailinglist-rules.md;hb=HEAD
>
> regards,
>
> Kalle Sommer Nielsen
> ka...@php.net
>


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

2021-03-28 Thread Andreas Leathley

On 27.03.21 17:05, Rowan Tommins wrote:

My biggest concern with automatic capture is the potential for
*accidentally* capturing variables - that is, intending to introduce a
local variable inside the closure, but capturing a variable from the
outer scope that happens to have the same name. This is less of an
issue with capture by value, but can still mean resources not being
freed, e.g. a large array of data not being freed from memory, or an
object destructor not executing when expected.

This is more likely in PHP than many other languages, because there is
no requirement, or even an option, to explicitly declare a local
variable in the closure. It's not a new problem, but since
single-expression closures are unlikely to use many local variables,
it's probably not one that's been given lots of thought.


I do think it is great that you are thinking about how this can
negatively effect memory or performance (and things like destructors)
and if things can be improved. But do the same problems not exist when
binding the current class to an anonymous function - whenever an
anonymous function is declared in a class (no matter if by function or
fn) the whole class is bound to that function, if you don't explicitely
use "static function". That binding can encompass many variables and
other classes etc., which is common nowadays with dependency injection,
yet I have not heard much about problems surrounding this. Binding the
variables from the current scope seems like a smaller impact compared to
already binding the whole class and all its dependencies.

I would welcome any way of automatically capturing all local variables,
as this would be a big "quality-of-life" improvement similar to
constructor property promotion, to avoid a lot of boilerplate code. I
would not use it that much, but when I use it, it would be a big
improvement. Using "fn" for this seems consistent to me, and I don't
think people would always use it just because it is shorter - and IDEs
and static analyzers could detect and discourage use of "fn" if
"function" would be sufficient.

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



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

2021-03-28 Thread Kalle Sommer Nielsen
Den søn. 28. mar. 2021 kl. 13.02 skrev Deleu :
>
> This would lead to inconsistent behavior in the language when short closures 
> auto capture without the auto keyword while multi statements closure doesn't.
> One of the best features of these RFC are their cognitive definition that is 
> clear, concise, consistent and simple.

(First off, please read our mailing lists rules[1] and do not top post)

If we go by the inconsistent behavior then by that definition short
arrow functions are inconsistent with the rest of PHP as there is no
auto capture elsewhere.

This is not short arrow functions being expanded to support multi
lines, but rather the other way around, with multi line closures being
able to support auto capture which is identified by the `fn` keyword
and because of that, I would much rather have a `fn` be an alias of
`function` and then having the ability to put a keyword to declare
that you wish to use auto capture (which is consistent with the
exisiting design of PHP where you have to declare globals with the
`global` keyword or explicit imports to closures with the `use`
statement (which used to be done by the `lexical` keyword similarily
to the `global` keyword in early PHP 5.3.0 development) -- if you are
interested in this philosophy you can try lookup videos from some of
Rasmus' presentations where he explains his dislike with globals
coming from C). To back this up further, we also have the `static`
keyword which acts as a feature flag so it is not unnatural, the
naming of the keyword `auto` sure, but that is another discussion.

[1] 
https://git.php.net/?p=php-src.git;a=blob_plain;f=docs/mailinglist-rules.md;hb=HEAD

regards,

Kalle Sommer Nielsen
ka...@php.net

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



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

2021-03-28 Thread Deleu
This would lead to inconsistent behavior in the language when short
closures auto capture without the auto keyword while multi statements
closure doesn't.
One of the best features of these RFC are their cognitive definition that
is clear, concise, consistent and simple.

On Sun, Mar 28, 2021, 11:26 Kalle Sommer Nielsen  wrote:

> Hi Rowan
>
> Den lør. 27. mar. 2021 kl. 18.05 skrev Rowan Tommins <
> rowan.coll...@gmail.com>:
> > Based on those, there seems to be no way to prevent a variable being
> > captured, even if its value is immediately discarded each time the
> > closure runs. This may be less than ideal:
> >
> > $results = getLargeReportFromDatabase();
> > // ...
> > $fn = fn() {
> >  $results = []; // coincidentally the same name, immediately
> > assigned its own value
> >  // ...
> > }
> > unset($results); // does not free the array, because $fn has captured
> > the value
>
> I too am very concerned about this exact senario because it very
> easily overlooked. While I understand the appeal of having very short
> closures, I do think that such behavior needs to be explicit and would
> much rather prefer something like this:
>
>  - Make the `fn` keyword an alias of the `function` keyword
>  - Add a new `auto` (or similar)  keyword for explicit auto capture
>
> Something like this:
> ```php
> return function () use ($v1, $v2, $v3, $v4) {
> /* ... */
> };
> ```
>
> Would then be abled to be turned into:
> ```php
> return auto fn () {
> /* ... */
> };
> ```
>
> That way it is very clear that the closure is intending on auto
> capturing at this point, at the same time it also allows people like
> me who prefers the `function` keyword to write.
>
> I personally don't think adding those 5 extra characters here for
> explicitity is bad, I would like explicitly over implicitit, I can see
> how many would simply just write `fn` without knowing there is a very
> vitual difference (similar to `static` closures is rare if you don't
> intend on binding `$this`).
>
> --
> regards,
>
> Kalle Sommer Nielsen
> ka...@php.net
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
>
>


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

2021-03-28 Thread Kalle Sommer Nielsen
Hi Rowan

Den lør. 27. mar. 2021 kl. 18.05 skrev Rowan Tommins :
> Based on those, there seems to be no way to prevent a variable being
> captured, even if its value is immediately discarded each time the
> closure runs. This may be less than ideal:
>
> $results = getLargeReportFromDatabase();
> // ...
> $fn = fn() {
>  $results = []; // coincidentally the same name, immediately
> assigned its own value
>  // ...
> }
> unset($results); // does not free the array, because $fn has captured
> the value

I too am very concerned about this exact senario because it very
easily overlooked. While I understand the appeal of having very short
closures, I do think that such behavior needs to be explicit and would
much rather prefer something like this:

 - Make the `fn` keyword an alias of the `function` keyword
 - Add a new `auto` (or similar)  keyword for explicit auto capture

Something like this:
```php
return function () use ($v1, $v2, $v3, $v4) {
/* ... */
};
```

Would then be abled to be turned into:
```php
return auto fn () {
/* ... */
};
```

That way it is very clear that the closure is intending on auto
capturing at this point, at the same time it also allows people like
me who prefers the `function` keyword to write.

I personally don't think adding those 5 extra characters here for
explicitity is bad, I would like explicitly over implicitit, I can see
how many would simply just write `fn` without knowing there is a very
vitual difference (similar to `static` closures is rare if you don't
intend on binding `$this`).

-- 
regards,

Kalle Sommer Nielsen
ka...@php.net

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



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

2021-03-27 Thread Mike Schinkel
> On Mar 27, 2021, at 12:05 PM, Rowan Tommins  wrote:
> 
> On 27/03/2021 00:05, Nuno Maduro wrote:
>> 
>> I've just added a few more tests with the exact examples you have presented 
>> in this mail list: 
>> https://github.com/php/php-src/pull/6246/commits/c3a50d671c5d8fa4b775ec67fe77d0cbd5cc8030
>>  
>> .
> 
> 
> Hi Nuno,
> 
> Thanks, I hadn't thought of writing out test cases, that makes a lot of 
> sense; although I now realise my question wasn't very clear.
> 
> My biggest concern with automatic capture is the potential for *accidentally* 
> capturing variables - that is, intending to introduce a local variable inside 
> the closure, but capturing a variable from the outer scope that happens to 
> have the same name. This is less of an issue with capture by value, but can 
> still mean resources not being freed, e.g. a large array of data not being 
> freed from memory, or an object destructor not executing when expected.
> 
> This is more likely in PHP than many other languages, because there is no 
> requirement, or even an option, to explicitly declare a local variable in the 
> closure. It's not a new problem, but since single-expression closures are 
> unlikely to use many local variables, it's probably not one that's been given 
> lots of thought.
> 
> 
> I've written some tests that demonstrate the current behaviour using an 
> object destructor: 
> https://github.com/nunomaduro/php-src/commit/ae18662cc92f5d07520b4574dcae71d38a9e0a41
> 
> Based on those, there seems to be no way to prevent a variable being 
> captured, even if its value is immediately discarded each time the closure 
> runs. This may be less than ideal:
> 
> $results = getLargeReportFromDatabase();
> // ...
> $fn = fn() {
> $results = []; // coincidentally the same name, immediately assigned its 
> own value
> // ...
> }
> unset($results); // does not free the array, because $fn has captured the 
> value

In this case doesn't $results get released when $fn goes out of scope?  

IOW, if fn() is used and discarded by the end of the function in which is it 
declared then this accidental capture is not an issue (unless it breaks the 
outer code, of course), right?

If it breaks in the outer code then I would say that is not really any 
different than overwriting the variable in a later loop, for example. So not 
really an indictment of auto-capture.

It is only if the function allows the closure to live on by returned it 
directly or indirectly, assigning it to a by-reference parameter or assigning 
to a property of an object that was passed in that it can "leak."

Which then begs the question of "How often do closure get returned in a manner 
they have a long life AND a large number of the same types of closures are 
created?  I can envision how that might happen, but I question how common that 
scenario would be?

And finally, most to the time a PHP page terminates after a page load thus 
releasing all these captured variables.  Yes CLI apps and "Fiber" apps might be 
different, but they are certainly less common than request/response web pages.

IOW, it feels like there would need be a confluence of many factors that 
collectively are likely rare before this scenario could become a real problem. 

Where one solution would be, of course, to not write long functions such that 
it is hard to identify accidentally captured variables. Which seems like a best 
practice anyway?

Did I get anything wrong above? I don't think so but then I could well have 
missed something.

In summary, is this accidental-capture-which-turns-into-a-resource-leak 
actually a problem worth worrying about?


> I wonder if the capture analysis could be made smarter to make this less 
> likely.
> 
> 
> PS I'd like to apologise if some of my messages in this thread have come 
> across as harsh or demanding, I do appreciate you bringing up this feature, 
> as I know it's one a lot of people want, even if I'm sceptical.
> 
> Regards,
> 
> -- 
> Rowan Tommins
> [IMSoP]
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
> 

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



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

2021-03-27 Thread Rowan Tommins

On 27/03/2021 16:52, Larry Garfield wrote:

It's a valid point that auto-capture on multi-line function makes the potential 
for unexpected behavior higher than with a single-line function, simply by 
virtue of there being more lines of code that could do so.



It's not just about number of lines, but style of code: the vast 
majority of single-expression closures will have zero local variables, 
so the potential for accidentally capturing a variable of the same name 
is also zero.


You're right that it's subjective whether this risk is too high, though. 
I was partly trying to understand what the risk is with the proposed 
behaviour, and also considering whether we can reduce that risk by 
changing the implementation to capture fewer variables.



This did come up in some of the previous discussions. For instance, 
during the discussion of the successful RFC two years ago, Nikita wrote 
[ https://externals.io/message/104693#104738 ]:


> On the other hand, allowing a block body for the closure does add a 
number

> of complications to this proposal:
> [...]
> 3. Determining bound variables. For single-expression closures we can 
get
> away with binding all variables that are used inside the closure. 
Writing
> something like fn() $a = $b might cause an unnecessary binding of $a, 
but

> it's also a very contrived situation. For block closures performing
> assignments inside the closure will be much more common and will need 
some

> more consideration to avoid unnecessary bindings.


Regards,

--
Rowan Tommins
[IMSoP]

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



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

2021-03-27 Thread Larry Garfield
On Sat, Mar 27, 2021, at 11:05 AM, Rowan Tommins wrote:
> On 27/03/2021 00:05, Nuno Maduro wrote:
> >
> > I've just added a few more tests with the exact examples you have 
> > presented in this mail list: 
> > https://github.com/php/php-src/pull/6246/commits/c3a50d671c5d8fa4b775ec67fe77d0cbd5cc8030
> >  
> > .
> 
> 
> Hi Nuno,
> 
> Thanks, I hadn't thought of writing out test cases, that makes a lot of 
> sense; although I now realise my question wasn't very clear.
> 
> My biggest concern with automatic capture is the potential for 
> *accidentally* capturing variables - that is, intending to introduce a 
> local variable inside the closure, but capturing a variable from the 
> outer scope that happens to have the same name. This is less of an issue 
> with capture by value, but can still mean resources not being freed, 
> e.g. a large array of data not being freed from memory, or an object 
> destructor not executing when expected.
> 
> This is more likely in PHP than many other languages, because there is 
> no requirement, or even an option, to explicitly declare a local 
> variable in the closure. It's not a new problem, but since 
> single-expression closures are unlikely to use many local variables, 
> it's probably not one that's been given lots of thought.
> 
> 
> I've written some tests that demonstrate the current behaviour using an 
> object destructor: 
> https://github.com/nunomaduro/php-src/commit/ae18662cc92f5d07520b4574dcae71d38a9e0a41
> 
> Based on those, there seems to be no way to prevent a variable being 
> captured, even if its value is immediately discarded each time the 
> closure runs. This may be less than ideal:
> 
> $results = getLargeReportFromDatabase();
> // ...
> $fn = fn() {
>      $results = []; // coincidentally the same name, immediately 
> assigned its own value
>      // ...
> }
> unset($results); // does not free the array, because $fn has captured 
> the value
> 
> 
> I wonder if the capture analysis could be made smarter to make this less 
> likely.
> 
> 
> PS I'd like to apologise if some of my messages in this thread have come 
> across as harsh or demanding, I do appreciate you bringing up this 
> feature, as I know it's one a lot of people want, even if I'm sceptical.
> 
> Regards,

It's a valid point that auto-capture on multi-line function makes the potential 
for unexpected behavior higher than with a single-line function, simply by 
virtue of there being more lines of code that could do so.  The question is 
whether that higher risk is worth the improved ergonomics.  That is, 
ultimately, a subjective question, and depends on how much you think the risk 
increases (it's non-zero, but that doesn't mean high) and how much you think 
the ergonomics are improved (also non-zero, but hard to quantify).

IMO, it is.  In practice, I can't recall seeing 100 line closures inside 100 
functions, well, ever.  I mostly see 2-3 line closures in 10 line functions.  
That makes the risk vastly smaller, and in practice I don't think it will come 
up much.

Also, bear in mind that in many cases such bugs would become self-evident very 
quickly, and you'll know to just rename a variable.

I realize it's completely and totally unscientific, but the social media 
response to both of these RFCs has been overwhelmingly (although not 
universally) positive.  There definitely seems to be demand for "do the same 
stuff but with less typing".

--Larry Garfield

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



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

2021-03-27 Thread Rowan Tommins

On 27/03/2021 00:05, Nuno Maduro wrote:


I've just added a few more tests with the exact examples you have 
presented in this mail list: 
https://github.com/php/php-src/pull/6246/commits/c3a50d671c5d8fa4b775ec67fe77d0cbd5cc8030 
.



Hi Nuno,

Thanks, I hadn't thought of writing out test cases, that makes a lot of 
sense; although I now realise my question wasn't very clear.


My biggest concern with automatic capture is the potential for 
*accidentally* capturing variables - that is, intending to introduce a 
local variable inside the closure, but capturing a variable from the 
outer scope that happens to have the same name. This is less of an issue 
with capture by value, but can still mean resources not being freed, 
e.g. a large array of data not being freed from memory, or an object 
destructor not executing when expected.


This is more likely in PHP than many other languages, because there is 
no requirement, or even an option, to explicitly declare a local 
variable in the closure. It's not a new problem, but since 
single-expression closures are unlikely to use many local variables, 
it's probably not one that's been given lots of thought.



I've written some tests that demonstrate the current behaviour using an 
object destructor: 
https://github.com/nunomaduro/php-src/commit/ae18662cc92f5d07520b4574dcae71d38a9e0a41


Based on those, there seems to be no way to prevent a variable being 
captured, even if its value is immediately discarded each time the 
closure runs. This may be less than ideal:


$results = getLargeReportFromDatabase();
// ...
$fn = fn() {
    $results = []; // coincidentally the same name, immediately 
assigned its own value

    // ...
}
unset($results); // does not free the array, because $fn has captured 
the value



I wonder if the capture analysis could be made smarter to make this less 
likely.



PS I'd like to apologise if some of my messages in this thread have come 
across as harsh or demanding, I do appreciate you bringing up this 
feature, as I know it's one a lot of people want, even if I'm sceptical.


Regards,

--
Rowan Tommins
[IMSoP]

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



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

2021-03-26 Thread Nuno Maduro
Rowan,

I've just added a few more tests with the exact examples you have presented
in this mail list:
https://github.com/php/php-src/pull/6246/commits/c3a50d671c5d8fa4b775ec67fe77d0cbd5cc8030
.

On Fri, 26 Mar 2021 at 16:48, Olle Härstedt  wrote:

> 2021-03-26 17:11 GMT+01:00, Mike Schinkel :
> >> On Mar 26, 2021, at 8:12 AM, Olle Härstedt 
> >> wrote:
> >>
> >> 2021-03-26 3:38 GMT+01:00, Mike Schinkel :
> >>>
> >>>
>  On Mar 25, 2021, at 4:09 PM, Olle Härstedt 
>  wrote:
> 
>  2021-03-25 17:49 GMT+01:00, Mike Schinkel :
> >> On Mar 25, 2021, at 11:22 AM, Olle Härstedt  >
> >> wrote:
> >>
> >> 2021-03-25 16:02 GMT+01:00, Mike Schinkel :
> >>>
> >>>
>  On Mar 25, 2021, at 10:41 AM, Rowan Tommins
>  
>  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 

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

2021-03-26 Thread Olle Härstedt
2021-03-26 17:11 GMT+01:00, Mike Schinkel :
>> On Mar 26, 2021, at 8:12 AM, Olle Härstedt 
>> wrote:
>>
>> 2021-03-26 3:38 GMT+01:00, Mike Schinkel :
>>>
>>>
 On Mar 25, 2021, at 4:09 PM, Olle Härstedt 
 wrote:

 2021-03-25 17:49 GMT+01:00, Mike Schinkel :
>> On Mar 25, 2021, at 11:22 AM, Olle Härstedt 
>> wrote:
>>
>> 2021-03-25 16:02 GMT+01:00, Mike Schinkel :
>>>
>>>
 On Mar 25, 2021, at 10:41 AM, Rowan Tommins
 
 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 

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

2021-03-26 Thread Mike Schinkel
> On Mar 26, 2021, at 8:12 AM, Olle Härstedt  wrote:
> 
> 2021-03-26 3:38 GMT+01:00, Mike Schinkel :
>> 
>> 
>>> On Mar 25, 2021, at 4:09 PM, Olle Härstedt 
>>> wrote:
>>> 
>>> 2021-03-25 17:49 GMT+01:00, Mike Schinkel :
> On Mar 25, 2021, at 11:22 AM, Olle Härstedt 
> wrote:
> 
> 2021-03-25 16:02 GMT+01:00, Mike Schinkel :
>> 
>> 
>>> On Mar 25, 2021, at 10:41 AM, Rowan Tommins 
>>> 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 

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

2021-03-26 Thread Olle Härstedt
2021-03-26 3:38 GMT+01:00, Mike Schinkel :
>
>
>> On Mar 25, 2021, at 4:09 PM, Olle Härstedt 
>> wrote:
>>
>> 2021-03-25 17:49 GMT+01:00, Mike Schinkel :
 On Mar 25, 2021, at 11:22 AM, Olle Härstedt 
 wrote:

 2021-03-25 16:02 GMT+01:00, Mike Schinkel :
>
>
>> On Mar 25, 2021, at 10:41 AM, Rowan Tommins 
>> 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 

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

2021-03-25 Thread Mike Schinkel
> On Mar 25, 2021, at 1:57 PM, Rowan Tommins  wrote:
> 
> On 25/03/2021 17:14, Mike Schinkel wrote:
>> Are you proposing auto-capture but one that is note able to change the 
>> variable's value in the outer scope?
> 
> 
> I'm not proposing that, Nuno is. That's what this RFC proposes.

Your earlier comment confused me. I thought you were describing a genuine 
concern when you mentioned by-value — so I assumed the RFC had asked for by-ref 
even though I did not think it had. 

But instead you were being disingenuous by not answering a legitimate question 
and instead implying that those who support the RFC lack reason and that they 
should just accept the status quo (copied below for reference):

> On Mar 25, 2021, at 12:50 PM, Rowan Tommins  wrote:
> On 25/03/2021 15:02, Mike Schinkel wrote:
>> Can you please clarify why "function(...) use(...) {...}" can't be their 
>> solution when someone needs by-reference capture?
> For the same reason - or lack of reason - why it can't be the solution when 
> they need by-value capture. In other words, whatever reason people have for 
> wanting this RFC.

Instead, why not simply state your position against the RFC transparently — as 
you eventually did in another reply — and leave it at that?  Then the deciders 
can go off and make their decisions on the RFC as they will.


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



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

2021-03-25 Thread Mike Schinkel



> On Mar 25, 2021, at 4:09 PM, Olle Härstedt  wrote:
> 
> 2021-03-25 17:49 GMT+01:00, Mike Schinkel :
>>> On Mar 25, 2021, at 11:22 AM, Olle Härstedt 
>>> wrote:
>>> 
>>> 2021-03-25 16:02 GMT+01:00, Mike Schinkel :
 
 
> On Mar 25, 2021, at 10:41 AM, Rowan Tommins 
> 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?  

> Maybe more important than explicit/implicit capturing of scope is to
> keep your functions short...? In our legacy code-base, we have functions
> 

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

2021-03-25 Thread Olle Härstedt
2021-03-25 17:49 GMT+01:00, Mike Schinkel :
>> On Mar 25, 2021, at 11:22 AM, Olle Härstedt 
>> wrote:
>>
>> 2021-03-25 16:02 GMT+01:00, Mike Schinkel :
>>>
>>>
 On Mar 25, 2021, at 10:41 AM, Rowan Tommins 
 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).

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. 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?

Never the less, the need to include 5+ variables in your closure -
code smell? I stated above that command pattern and data-transfer
objects are probably better, and that's why I think the example in the
RFC is not motivating enough.

The question is not "what do I want to be able to write", but rather
"what do I want to be forced to read [by less qualified programmers]".

> For some people, shorter makes it more readable because there is less to
> read and more whitespace surrounding it. Ironically readability is why I
> prefer fn() w/autocapture over "function(...) use (...) {...}."
>
> Also, it appears you may be discounting that readablity evolves as people's
> familiarity with a new syntax increases.  For example, I found RegEx
> completely unreadable for a long 

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

2021-03-25 Thread Mike Schinkel
> On Mar 25, 2021, at 1:19 PM, Chase Peeler  wrote:
> 
> On Thu, Mar 25, 2021 at 1:14 PM Mike Schinkel  > wrote:
> > On Mar 25, 2021, at 12:50 PM, Rowan Tommins  > > wrote:
> > 
> > On 25/03/2021 15:02, Mike Schinkel wrote:
> >> Can you please clarify why "function(...) use(...) {...}" can't be their 
> >> solution when someone needs by-reference capture?
> > 
> > 
> > For the same reason - or lack of reason - why it can't be the solution when 
> > they need by-value capture. In other words, whatever reason people have for 
> > wanting this RFC.
> 
> Are you proposing auto-capture but one that is note able to change the 
> variable's value in the outer scope?  
> 
> Since code is worth 1000 words, here is an example of what I think you are 
> saying:
> 
> $x = 1;
> example(fn() {
>echo $x; // This would print "1"
>$x = 2;
>echo $x; // This would print "2"
> });
> echo $x;  // This would still print "1"
> 
> If that is what you are saying — which I did not get from your prior 
> arguments — then I myself would be fine with "by-value" capture.
> 
> What I like about the RFC is being able to omit the use(...) when referencing 
> (reading) a variable inside the closure that come from the outer scope.  But 
> almost all of my use-cases would work fine with by-value semantics, and for 
> the rest I could use "function(...)use(...){...}."
> 
> That said, I again suggest this we could omit the "use" keyword for short 
> functions:  
> 
> // 2nd set of parens acts as an implied "use":
> example( fn()(&$var) => $var = value() );
> 
> 
> That wouldn't work though if example expects a callback with a defined 
> signature. "Use function() use()" in that case might be a valid solution, but 
> just wanted to throw it out there.


True.  But is that really any different than this failing:

example(1);

When the signature is this?

example(string $x) {...}

-Mike



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

2021-03-25 Thread Rowan Tommins

On 25/03/2021 17:14, Mike Schinkel wrote:

Are you proposing auto-capture but one that is note able to change the 
variable's value in the outer scope?



I'm not proposing that, Nuno is. That's what this RFC proposes.


Regards,

--
Rowan Tommins
[IMSoP]

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



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

2021-03-25 Thread Rowan Tommins

On 25/03/2021 17:11, Chase Peeler wrote:
I don't think you should keep a function from developers because some 
people might use it incorrectly.



That is not what I said either.

I said I am not a fan of the "fn" syntax, because I do not think 
auto-capture should be seen as the default.


If consensus is that we need auto-capture in the language, I would 
prefer a syntax that clearly shows that you are opting into it.



Regards,

--
Rowan Tommins
[IMSoP]

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



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

2021-03-25 Thread Chase Peeler
On Thu, Mar 25, 2021 at 1:14 PM Mike Schinkel  wrote:

> > On Mar 25, 2021, at 12:50 PM, Rowan Tommins 
> wrote:
> >
> > On 25/03/2021 15:02, Mike Schinkel wrote:
> >> Can you please clarify why "function(...) use(...) {...}" can't be
> their solution when someone needs by-reference capture?
> >
> >
> > For the same reason - or lack of reason - why it can't be the solution
> when they need by-value capture. In other words, whatever reason people
> have for wanting this RFC.
>
> Are you proposing auto-capture but one that is note able to change the
> variable's value in the outer scope?
>
> Since code is worth 1000 words, here is an example of what I think you are
> saying:
>
> $x = 1;
> example(fn() {
>echo $x; // This would print "1"
>$x = 2;
>echo $x; // This would print "2"
> });
> echo $x;  // This would still print "1"
>
> If that is what you are saying — which I did not get from your prior
> arguments — then I myself would be fine with "by-value" capture.
>
> What I like about the RFC is being able to omit the use(...) when
> referencing (reading) a variable inside the closure that come from the
> outer scope.  But almost all of my use-cases would work fine with by-value
> semantics, and for the rest I could use "function(...)use(...){...}."
>
> That said, I again suggest this we could omit the "use" keyword for short
> functions:
>
> // 2nd set of parens acts as an implied "use":
> example( fn()(&$var) => $var = value() );
>
>
That wouldn't work though if example expects a callback with a defined
signature. "Use function() use()" in that case might be a valid solution,
but just wanted to throw it out there. Silly example:

$counter = 0;
array_map(fn($a) => {$counter++; return $a+1},$array);

If you tried to pass in $counter as a parameter, it would fail.


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

-- 
Chase Peeler
chasepee...@gmail.com


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

2021-03-25 Thread Mike Schinkel
> On Mar 25, 2021, at 12:50 PM, Rowan Tommins  wrote:
> 
> On 25/03/2021 15:02, Mike Schinkel wrote:
>> Can you please clarify why "function(...) use(...) {...}" can't be their 
>> solution when someone needs by-reference capture?
> 
> 
> For the same reason - or lack of reason - why it can't be the solution when 
> they need by-value capture. In other words, whatever reason people have for 
> wanting this RFC.

Are you proposing auto-capture but one that is note able to change the 
variable's value in the outer scope?  

Since code is worth 1000 words, here is an example of what I think you are 
saying:

$x = 1;
example(fn() {
   echo $x; // This would print "1"
   $x = 2;
   echo $x; // This would print "2"
});
echo $x;  // This would still print "1"

If that is what you are saying — which I did not get from your prior arguments 
— then I myself would be fine with "by-value" capture.

What I like about the RFC is being able to omit the use(...) when referencing 
(reading) a variable inside the closure that come from the outer scope.  But 
almost all of my use-cases would work fine with by-value semantics, and for the 
rest I could use "function(...)use(...){...}."

That said, I again suggest this we could omit the "use" keyword for short 
functions:  

// 2nd set of parens acts as an implied "use":
example( fn()(&$var) => $var = value() );

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



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

2021-03-25 Thread Chase Peeler
On Thu, Mar 25, 2021 at 12:47 PM Rowan Tommins 
wrote:

> On 25/03/2021 15:05, Deleu wrote:
> > > * 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.
> >
> > Does this mean you agree that people (PHP users) are very likely to
> > like/enjoy/"think it's the better version", but you still object to it
> > because people will like the new syntax so much that they will use it
> > even when they don't need auto-capture?
>
>
> No, it does not.
>
> I think that people who have no idea how either version of the syntax
> works will decide that the keyword "fn" is easier to type than
> "function", and not realise the far-reaching effect this can have on
> their code.
>
>
I don't think you should keep a function from developers because some
people might use it incorrectly. Make sure it is documented properly and
stop worrying about people that ignore the documentation.


> Regards,
>
> --
> Rowan Tommins
> [IMSoP]
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
>
>

-- 
Chase Peeler
chasepee...@gmail.com


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

2021-03-25 Thread Rowan Tommins

On 25/03/2021 15:02, Mike Schinkel wrote:

Can you please clarify why "function(...) use(...) {...}" can't be their 
solution when someone needs by-reference capture?



For the same reason - or lack of reason - why it can't be the solution 
when they need by-value capture. In other words, whatever reason people 
have for wanting this RFC.



Regards,

--
Rowan Tommins
[IMSoP]

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



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

2021-03-25 Thread Mike Schinkel
> On Mar 25, 2021, at 11:22 AM, Olle Härstedt  wrote:
> 
> 2021-03-25 16:02 GMT+01:00, Mike Schinkel :
>> 
>> 
>>> On Mar 25, 2021, at 10:41 AM, Rowan Tommins 
>>> 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.  

For some people, shorter makes it more readable because there is less to read 
and more whitespace surrounding it. Ironically readability is why I prefer fn() 
w/autocapture over "function(...) use (...) {...}."

Also, it appears you may be discounting that readablity evolves as people's 
familiarity with a new syntax increases.  For example, I found RegEx completely 
unreadable for a long time, but today I find them completely readable because I 
now understand them. Have you already considered whether or not you would still 
find fn() w/autocapture less readable even after you have more time and 
experience seeing it in other people's code, and decided that you would still 
find it less readable?

I do recognize that ever developer has their own preference and I am sensing 
that your preference is for more verbose syntax, at least in this case? If that 
is true shouldn't you just state that more verbose is your preference and if 
you have a vote then vote against the RFC? Isn't it unfair to implictly assert 
that "shorter is less readable" when really it is just a preference?

-Mike

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



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

2021-03-25 Thread Rowan Tommins

On 25/03/2021 15:05, Deleu wrote:

> * 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.

Does this mean you agree that people (PHP users) are very likely to 
like/enjoy/"think it's the better version", but you still object to it 
because people will like the new syntax so much that they will use it 
even when they don't need auto-capture?



No, it does not.

I think that people who have no idea how either version of the syntax 
works will decide that the keyword "fn" is easier to type than 
"function", and not realise the far-reaching effect this can have on 
their code.


Regards,

--
Rowan Tommins
[IMSoP]

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



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

2021-03-25 Thread Chase Peeler
On Thu, Mar 25, 2021 at 11:23 AM Olle Härstedt 
wrote:

> 2021-03-25 16:02 GMT+01:00, Mike Schinkel :
> >
> >
> >> On Mar 25, 2021, at 10:41 AM, Rowan Tommins 
> >> 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'm a bit confused on why "shorter" is such an important requirement as
well. We aren't in a situation where memory is at a premium and we have to
take shortcuts to get our code to fit in the available storage. I also
assume that none of us are such slow typers that there is a material
difference between the options. On top of that, most IDEs worth anything
have autocomplete options that make it moot.

I agree that shorter definitely does not always mean more readable. If so,
we'd be taught to give all of our functions and variables single character
names instead of names that were descriptive.

I'm totally in favor of auto capture with the fn() syntax, but I think the
fact that its shorter is not the best argument to support it.



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

-- 
Chase Peeler
chasepee...@gmail.com


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

2021-03-25 Thread Olle Härstedt
2021-03-25 16:02 GMT+01:00, Mike Schinkel :
>
>
>> On Mar 25, 2021, at 10:41 AM, Rowan Tommins 
>> 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.

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



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

2021-03-25 Thread Deleu
> * 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.

Does this mean you agree that people (PHP users) are very likely to
like/enjoy/"think it's the better version", but you still object to it
because people will like the new syntax so much that they will use it even
when they don't need auto-capture?


On Thu, Mar 25, 2021 at 3:41 PM Rowan Tommins 
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.
> * There is no obvious way to expand it to support any by-reference
> capture, which is something people have previously expressed a desire for.
>
>
> Regards,
>
> --
> Rowan Tommins
> [IMSoP]
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
>
>

-- 
Marco Aurélio Deleu


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

2021-03-25 Thread Mike Schinkel



> On Mar 25, 2021, at 10:41 AM, Rowan Tommins  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.

> * There is no obvious way to expand it to support any by-reference capture, 
> which is something people have previously expressed a desire for.

Can you please clarify why "function(...) use(...) {...}" can't be their 
solution when someone needs by-reference capture?

-Mike

P.S. BTW, if we *had* to enable by-ref for "fn(...)" then I would argue it 
should be a terse syntax, e.g.:

$callable = fn()(&$foo) => $foo= bar();

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



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

2021-03-25 Thread Rowan Tommins

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.
* There is no obvious way to expand it to support any by-reference 
capture, which is something people have previously expressed a desire for.



Regards,

--
Rowan Tommins
[IMSoP]

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



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

2021-03-25 Thread Olle Härstedt
I feel like some of these examples would be better covered by command
object pattern and data-transaction objects, instead of FP idioms.
wrap_in_buffer pretty clearly so.

2021-03-25 10:28 GMT+01:00, Rowan Tommins :
> On 25/03/2021 04:12, Mike Schinkel wrote:
>
>> Actually, there is a way to declare a local variable.  Use the long
>> function syntax instead as there is no proposal to deprecate it.
>
> That's not quite what I meant. I meant that you can't say "capture by
> default, but this variable is definitely local".
>
> I'm guessing maybe "$foo = null;" at the top of the function would stop
> it auto-capturing, but the semantics of what exactly gets captured
> aren't spelled out in the RFC. That really needs to be added IMO.
>
>
>> Instead of using array_filter() with a side-effect free closure, I use a
>> for loop because it is easier to reason about visually.
>
>
> Is that a bad thing? In many cases it's probably more efficient, and
> easier to read.
>
>
>
>
>> It is not clear to me from reading the PEP how a "with" statement obviates
>> the benefit of variable auto-capture? Maybe because I don't "think" in
>> Python, so from reading their examples I cannot see how this relates?
>
>
> I didn't mean to say that the "with" statement would replace closures in
> general, but it would make them unnecessary *for some specific use
> cases*. You mentioned:
>
>  > prime examples are database transactions and using throw-aware
> buffering handlers.
>
> If your current code looks something like this:
>
> wrap_in_buffer(function($transaction) use ($to, $library, $thread,
> $author, $title, $library_name, $top_post) {
>  doSomething($to, $library, $thread);
>  andThenSomethingElse($author, $title, $library_name, $top_post);
> });
>
> That's a perfect use case for a Context Manager:
>
> with ( wrap_in_buffer() ) {
>  doSomething($to, $library, $thread);
>  andThenSomethingElse($author, $title, $library_name, $top_post);
> }
>
> There's no callback, so no need to capture anything, and the
> implementation of all the try-catch-finally logic would be baked into
> the language, so the implementation of wrap_in_buffer() would also be
> much simpler.
>
>
> Regards,
>
> --
> Rowan Tommins
> [IMSoP]
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
>
>

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



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

2021-03-25 Thread Olle Härstedt
> prettier to read

Are they though? Because if it implicitly captures anything in scope,
there are more lines to read to figure out what's actually captured.

2021-03-25 13:31 GMT+01:00, Nuno Maduro :
> Hi,
>
> Thank you for the feedback on this thread so far. Programmers are
> opinionated, therefore you will find developers that see themselves using
> this RFC and others who don't. Just like "Fibers", "Type-hints", or any
> other feature in the language really.
>
> 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. [1]
>
> 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. And, the "=>" sigil always means
> "evaluates to the expression on the right" in all circumstances - one-line
> short closures, named functions, arrays, and match() already follow these
> patterns. [3]
>
> On the other hand "use (*)" has no usages / or current meaning in the
> language.
>
> Thanks,
> Nuno.
>
> [1] Pretty much "Brent Roose" have said here:
> https://externals.io/email/112010/source
> [2] https://wiki.php.net/rfc/short-functions
> [3] Check "Auto-capture multi-statement closures" -
> https://wiki.php.net/rfc/auto-capture-closure.
>

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



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

2021-03-25 Thread Mike Schinkel
> On Mar 25, 2021, at 5:28 AM, Rowan Tommins  wrote:
> 
> On 25/03/2021 04:12, Mike Schinkel wrote:
> 
>> Actually, there is a way to declare a local variable.  Use the long function 
>> syntax instead as there is no proposal to deprecate it.
> 
> That's not quite what I meant. I meant that you can't say "capture by 
> default, but this variable is definitely local".


Yes I can see you want a way to declare a local in an auto-capturing fn(), but 
respectfully I do not see why using the function() syntax is not a viable 
alternate solution when and if you want to explicitly not capture a variable.

I said "want" because you will never *need* to as you can always use a variable 
name that is not in the outer scope. 

And yes I know, someone may come along later and add a named variable in the 
outer scope that matches your implicit local variable's name and potentially 
break your code, but again if that is a concern why can't you just use 
function() instead of fn()?  And wouldn't they actually be breaking their code 
(the outer code) if they did this?

Respectfully, you seem to be calling out a problem for which there is a 
tailor-designed solution explicitly recommended in the RFC. How can function() 
not address your stated concern?


> I'm guessing maybe "$foo = null;" at the top of the function would stop it 
> auto-capturing, but the semantics of what exactly gets captured aren't 
> spelled out in the RFC. That really needs to be added IMO.
> 
> 
>> Instead of using array_filter() with a side-effect free closure, I use a for 
>> loop because it is easier to reason about visually.
> 
> Is that a bad thing? In many cases it's probably more efficient, and easier 
> to read.


Depends on what your priorities are.  If you priorities are coding in the 
absolute most efficient manner and/or with the most clarity, no it is probably 
not a bad thing.

But if your priorities are coding in the most robust manner where your code is 
free from side-effects by design — in a functional style —  and the performance 
difference is insignificant, then yes it is a bad thing. 

And at least one of the pair of RFCs spell out this motivation to allow for 
more functional style explicitly. 


>> It is not clear to me from reading the PEP how a "with" statement obviates 
>> the benefit of variable auto-capture? Maybe because I don't "think" in 
>> Python, so from reading their examples I cannot see how this relates?
> 
> I didn't mean to say that the "with" statement would replace closures in 
> general, but it would make them unnecessary *for some specific use cases*.


Respectfully again, to argue a use-case could be addressed in a different way 
than proposed by the RFC when that different way uses a hypothetical language 
feature that AFAIK does not have an RFC currently under consideration rings 
hollow to me.

Minimally I would expect you to at least first float the hypothetical on the 
list to see if there is appetite for it rather than just using is idea to snipe 
at an RFC that many people appear to support.


> You mentioned:
> 
> > prime examples are database transactions and using throw-aware buffering 
> > handlers.


Actually, I did not provide that example. Other people did.  

What I stated was I had other use-cases that concerned me more than 
transactions, which I already explained in my email. 

However, in no way do I mean to argue against their value for other developers 
who mentioned them.


> If your current code looks something like this:
> 
> wrap_in_buffer(function($transaction) use ($to, $library, $thread, $author, 
> $title, $library_name, $top_post) {
> doSomething($to, $library, $thread);
> andThenSomethingElse($author, $title, $library_name, $top_post);
> });
> 
> That's a perfect use case for a Context Manager:
> 
> with ( wrap_in_buffer() ) {
> doSomething($to, $library, $thread);
> andThenSomethingElse($author, $title, $library_name, $top_post);
> }
> 
> There's no callback, so no need to capture anything, and the implementation 
> of all the try-catch-finally logic would be baked into the language, so the 
> implementation of wrap_in_buffer() would also be much simpler.


But thanks for clarifying with examples, because I did ask for that.

That said, "with" is still hypothetical.  Are you planning to champion its 
inclusion into PHP with a discussion and then follow up RFC?

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



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

2021-03-25 Thread Nuno Maduro
Hi,

Thank you for the feedback on this thread so far. Programmers are
opinionated, therefore you will find developers that see themselves using
this RFC and others who don't. Just like "Fibers", "Type-hints", or any
other feature in the language really.

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. [1]

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. And, the "=>" sigil always means
"evaluates to the expression on the right" in all circumstances - one-line
short closures, named functions, arrays, and match() already follow these
patterns. [3]

On the other hand "use (*)" has no usages / or current meaning in the
language.

Thanks,
Nuno.

[1] Pretty much "Brent Roose" have said here:
https://externals.io/email/112010/source
[2] https://wiki.php.net/rfc/short-functions
[3] Check "Auto-capture multi-statement closures" -
https://wiki.php.net/rfc/auto-capture-closure.


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

2021-03-25 Thread Rowan Tommins

On 25/03/2021 04:12, Mike Schinkel wrote:


Actually, there is a way to declare a local variable.  Use the long function 
syntax instead as there is no proposal to deprecate it.


That's not quite what I meant. I meant that you can't say "capture by 
default, but this variable is definitely local".


I'm guessing maybe "$foo = null;" at the top of the function would stop 
it auto-capturing, but the semantics of what exactly gets captured 
aren't spelled out in the RFC. That really needs to be added IMO.




Instead of using array_filter() with a side-effect free closure, I use a for 
loop because it is easier to reason about visually.



Is that a bad thing? In many cases it's probably more efficient, and 
easier to read.






It is not clear to me from reading the PEP how a "with" statement obviates the benefit of 
variable auto-capture? Maybe because I don't "think" in Python, so from reading their 
examples I cannot see how this relates?



I didn't mean to say that the "with" statement would replace closures in 
general, but it would make them unnecessary *for some specific use 
cases*. You mentioned:


> prime examples are database transactions and using throw-aware 
buffering handlers.


If your current code looks something like this:

wrap_in_buffer(function($transaction) use ($to, $library, $thread, 
$author, $title, $library_name, $top_post) {

    doSomething($to, $library, $thread);
    andThenSomethingElse($author, $title, $library_name, $top_post);
});

That's a perfect use case for a Context Manager:

with ( wrap_in_buffer() ) {
    doSomething($to, $library, $thread);
    andThenSomethingElse($author, $title, $library_name, $top_post);
}

There's no callback, so no need to capture anything, and the 
implementation of all the try-catch-finally logic would be baked into 
the language, so the implementation of wrap_in_buffer() would also be 
much simpler.



Regards,

--
Rowan Tommins
[IMSoP]

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



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

2021-03-24 Thread Peter Stalman
On Wed, Mar 24, 2021 at 2:26 PM Mark Randall  wrote:

> To give my own example, earlier this week I wrote the following:
>
> $x = function () use ($to, $library, $thread, $author, $title,
> $library_name, $top_post) { ... }
>
> That was just to get those variables inside a callback that could be
> invoked inside a throw-aware buffering helper.
>

Hi Mark,

Have you considered using an array or DTO to pass the data?

You could also do this (although I'm not advocating it):

```
$vars = get_defined_vars();
$x = function() use ($vars) {
extract($vars);
/* ... */
};
```

Thanks,
Peter


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

2021-03-24 Thread Mike Schinkel
> On Mar 24, 2021, at 6:45 PM, Rowan Tommins  wrote:
> 
> On 24/03/2021 21:26, Mark Randall wrote:
>> 
>> Automatic capture ceased to be a dramatic change from PHP the day after 
>> short closurers were introduced. So they've been a part of PHP for years 
>> now. 
> 
> 
> I strongly disagree. Short closures say "turn this expression into a 
> function". You would have to work really, really hard to introduce a 
> sufficient amount of complexity that scope was hard to follow.

Another perspective is that the short syntax reduces complexity by not needing 
to be as verbose. 

I just did a search through a few of my codebases and found that I almost never 
use more than one parameter, but I would still applaud this syntax. Why?

1.) Many of my use-cases for closure functions are within functions with only a 
few lines that simply return the closure, i.e these functions are names 
wrappers for the closure to simplify their reuse across the codebase.  Anyway, 
having to declare the variable twice, once as a function parameter and again in 
the use() on the next line is just tedious overkill, IMO.  

Then there are a use-cases with array_filter() and similar functions where the 
use() just adds visual complexity to what could otherwise be visually easier to 
reason about at a glance.

Probably the only use-case I can envision where auto-capture would be 
problematic would be when you do have really long functions. But if you have 
really long functions, don't you actually have a different problem that 
probably needs to be addressed first?

2.) This is subjective, but my workflow frequently has me splitting the screen 
vertically so I can view two related files side-by-side such as the calling 
code on one side and the code it calls on the other. For this use-case, I 
almost always find myself having to scroll horizontally whenever using a 
closure has a use() so I can see the use() variables. That is tedious and 
tiring.

So syntax that results in longer lines is problematic for my workflow. I know 
not everybody can relate but I have to believe that I am not the only one this 
affects. 

3.) This is also subjective, but because of the requirement for use() I often 
find myself *not* using a closure because of its visual noise, and the use() is 
the main contributor to the visual noise. Instead of using array_filter() with 
a side-effect free closure, I use a for loop because it is easier to reason 
about visually. 

If the short syntax existed I think I would more often use a closure. Maybe I 
am unique in this, but I am probably not. 

> Full-bodied auto-capture means you can introduce a variable on line 1, and 
> find it's never freed, because it was silently captured by a function on line 
> 200. Since there's no way to declare a local variable, you couldn't even opt 
> *out* of the capture, as "let" or "var" do in JavaScript.

Actually, there is a way to declare a local variable.  Use the long function 
syntax instead as there is no proposal to deprecate it.

Different syntaxes for different use-cases.

> I hit long lists of use() repeatedly, almost always because I need to perform 
> a series of operations within a callback, prime examples are database 
> transactions and using throw-aware buffering handlers. 
> 
> I think a lot of those use cases are using anonymous functions because 
> they're available, not because they're the best tool for the job.

For some of these use-cases, the auto-capture would be the best tool. 

But if we don't get variable auto-capture then for those use-cases we'd have no 
choice but to use the tool that is *not* the best tool for the job because it 
would be the only tool we'd have. 

> A transaction wrapper, for instance, doesn't actually need to pass control to 
> the transaction and back to a callback, it just needs some before and after 
> boilerplate.
> 
> 
> Python has a "with" syntax for this, which calls __enter__ and __exit__ 
> methods on a "Context Manager" object: 
> https://www.python.org/dev/peps/pep-0343/
> 
> Translating the syntax to look more PHP-ish, you'd write something like this:
> 
> with ( new Transaction($db) as $transaction ) {
> doSomething($to, $library, $thread);
> andThenSomethingElse($author, $title, $library_name, $top_post);
> }

So "with" is a statement, not an expression?  

Not sure how that helps since I thought one of the benefits of the short 
function syntax (with variable auto-capture) was to move away from procedural 
statements and toward more functional expressions?

> The compiler would then insert an appropriate try ... catch ... finally, with 
> no need for a callback, and therefore no need to capture lots of variables. 
> The full internal expansion is quite long, so I've posted it as a gist here: 
> https://gist.github.com/IMSoP/a4e316684415413dca8ec5debf51a812
> 
> This is simpler for the programmer (my example Transaction class is a total 
> of 20 lines long), more efficient at run-time (no extra stack frame for 

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

2021-03-24 Thread Rowan Tommins

On 24/03/2021 21:26, Mark Randall wrote:


Automatic capture ceased to be a dramatic change from PHP the day 
after short closurers were introduced. So they've been a part of PHP 
for years now. 



I strongly disagree. Short closures say "turn this expression into a 
function". You would have to work really, really hard to introduce a 
sufficient amount of complexity that scope was hard to follow.


Full-bodied auto-capture means you can introduce a variable on line 1, 
and find it's never freed, because it was silently captured by a 
function on line 200. Since there's no way to declare a local variable, 
you couldn't even opt *out* of the capture, as "let" or "var" do in 
JavaScript.



I hit long lists of use() repeatedly, almost always because I need to 
perform a series of operations within a callback, prime examples are 
database transactions and using throw-aware buffering handlers. 



I think a lot of those use cases are using anonymous functions because 
they're available, not because they're the best tool for the job.


A transaction wrapper, for instance, doesn't actually need to pass 
control to the transaction and back to a callback, it just needs some 
before and after boilerplate.



Python has a "with" syntax for this, which calls __enter__ and __exit__ 
methods on a "Context Manager" object: 
https://www.python.org/dev/peps/pep-0343/


Translating the syntax to look more PHP-ish, you'd write something like 
this:


with ( new Transaction($db) as $transaction ) {
    doSomething($to, $library, $thread);
    andThenSomethingElse($author, $title, $library_name, $top_post);
}

The compiler would then insert an appropriate try ... catch ... finally, 
with no need for a callback, and therefore no need to capture lots of 
variables. The full internal expansion is quite long, so I've posted it 
as a gist here: 
https://gist.github.com/IMSoP/a4e316684415413dca8ec5debf51a812


This is simpler for the programmer (my example Transaction class is a 
total of 20 lines long), more efficient at run-time (no extra stack 
frame for the callback), and possibly even simpler to compile (no 
analysis needed to work out what variables to capture).


Obviously, this doesn't cover all cases where automatic capture would be 
useful, but nor is it just a one-trick pony; the Python spec has lots of 
example use cases.



Regards,

--
Rowan Tommins
[IMSoP]

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



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

2021-03-24 Thread Chase Peeler
On Wed, Mar 24, 2021 at 5:26 PM Mark Randall  wrote:

> On 24/03/2021 21:00, Rowan Tommins wrote:
> > As Christian says, automatic capture is a dramatic change to the
> > language's scoping rules, and IMHO requires a more thorough
> > justification on why the current syntax is burdensome. As I've said
> > previously, my naive impression is that a long list of captured
> > variables ought to be as bad a code smell as a long list of parameters;
> > I'm willing to be proven wrong on this, but nobody has yet stepped
> > forward with a real-life example.
>
> Automatic capture ceased to be a dramatic change from PHP the day after
> short closurers were introduced. So they've been a part of PHP for years
> now.
>
> I hit long lists of use() repeatedly, almost always because I need to
> perform a series of operations within a callback, prime examples are
> database transactions and using throw-aware buffering handlers.
>

DB transaction is one place I have a long list of use parameters as well.
Since the goal is to do as much before we start the transaction as
possible, I always end up with a lot of variables resulting from that prep
work that I need to utilize inside the transaction callback.  My gut tells
me the use-cases for long use lists that don't indicate code smell are
pretty small though.



> In general, anything that needs to wrap a code block in a complex set of
> instructions before and after.
>
> To give my own example, earlier this week I wrote the following:
>
> $x = function () use ($to, $library, $thread, $author, $title,
> $library_name, $top_post) { ... }
>
> That was just to get those variables inside a callback that could be
> invoked inside a throw-aware buffering helper.
>
> I believe that by explicitly stating my intent to use auto capture by
> using fn() { ... } that my code would have been cleaner with less noise.
>
> If I thought otherwise, I would be under no obligation to use them and
> could use function() { ... } instead.
>

I agree. I think as long as we make it clear to users that function() does
not provide auto capture, but fn() does, we're fine. In the same way that
JavaScript make it clear that function(){} changes the meaning of "this"
while () => {} does not. The fact that they behave differently like that is
great in my opinion. I use function(){} when I want the changed context
(like event listener callbacks) and () => {} when I know I only need access
to the parent context and don't care about any possible redefinition.


>
> For me auto capture is a solid +1.
>
> Mark Randall
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
>
>

-- 
Chase Peeler
chasepee...@gmail.com


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

2021-03-24 Thread Mark Randall

On 24/03/2021 21:00, Rowan Tommins wrote:
As Christian says, automatic capture is a dramatic change to the 
language's scoping rules, and IMHO requires a more thorough 
justification on why the current syntax is burdensome. As I've said 
previously, my naive impression is that a long list of captured 
variables ought to be as bad a code smell as a long list of parameters; 
I'm willing to be proven wrong on this, but nobody has yet stepped 
forward with a real-life example.


Automatic capture ceased to be a dramatic change from PHP the day after 
short closurers were introduced. So they've been a part of PHP for years 
now.


I hit long lists of use() repeatedly, almost always because I need to 
perform a series of operations within a callback, prime examples are 
database transactions and using throw-aware buffering handlers.


In general, anything that needs to wrap a code block in a complex set of 
instructions before and after.


To give my own example, earlier this week I wrote the following:

$x = function () use ($to, $library, $thread, $author, $title, 
$library_name, $top_post) { ... }


That was just to get those variables inside a callback that could be 
invoked inside a throw-aware buffering helper.


I believe that by explicitly stating my intent to use auto capture by 
using fn() { ... } that my code would have been cleaner with less noise.


If I thought otherwise, I would be under no obligation to use them and 
could use function() { ... } instead.


For me auto capture is a solid +1.

Mark Randall

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