Hi folks. The vote for the Partial Function Application RFC is now open, and will run until 30 June.
https://wiki.php.net/rfc/partial_function_application
Of particular note, a few people had asked about using ...? instead of ... for the variadic placeholder. In the end we decided not to explore that, as Nikita explained off-list it was actually more confusing, not less, as it would suggest "placeholder for a variadic" rather than "a placeholder that is variadic." Otherwise, it's just more typing. The syntax choices section of the RFC has been updated accordingly.
--
Larry Garfield
larry@garfieldtech.com
Le Wed, 16 Jun 2021 11:16:28 -0500,
"Larry Garfield" larry@garfieldtech.com a écrit :
Hi folks. The vote for the Partial Function Application RFC is now open, and
will run until 30 June.
I do not understand how this ... placeholder works, it feels inconsistent.
From the examples:
$c = stuff(...);
$c = fn(int $i, string $s, float $f, Point $p, int $m = 0)
=> stuff($i, $s, $f, $p, $m);
$c = stuff(1, 'hi', 3.4, $point, 5, ...);
$c = fn(...$args) => stuff(1, 'hi', 3.4, $point, 5, ...$args);
Why is there an additional variadic parameter in this one?
If I remove the 5:
$c = stuff(1, 'hi', 3.4, $point, ...);
I get this right?:
$c = fn(int $m = 0) => stuff(1, 'hi', 3.4, $point, $m);
Why the ... does not produce 0 parameters when there are none left?
Also, in the second set of examples:
function things(int $i, float $f, Point ...$points) { ... }
// Ex 13
$c = things(...);
$c = fn(int $i, float $f, ...$args) => things(...[$i, $f, ...$args]);
// Ex 14
$c = things(1, 3.14, ...);
$c = fn(...$args) => things(...[1, 3.14, ...$args]);
What happens to the typing of the variadic parameter here? Why is it removed?
It would feel natural that the ... means "copy the rest of the parameters from
signature". Here it seems it sometimes mean that, and sometimes mean "accept an
additional variadic parameter and pass it along".
Côme
Le Wed, 16 Jun 2021 11:16:28 -0500,
"Larry Garfield" larry@garfieldtech.com a écrit :Hi folks. The vote for the Partial Function Application RFC is now open, and
will run until 30 June.I do not understand how this ... placeholder works, it feels inconsistent.
From the examples:
$c = stuff(...);
$c = fn(int $i, string $s, float $f, Point $p, int $m = 0)
=> stuff($i, $s, $f, $p, $m);$c = stuff(1, 'hi', 3.4, $point, 5, ...);
$c = fn(...$args) => stuff(1, 'hi', 3.4, $point, 5, ...$args);Why is there an additional variadic parameter in this one?
... means "zero or more". In this case, it means zero, that is, it creates a closure that requires no arguments and will call the original function with all of the provided values later. This is the "deferred function" use case mentioned further down.
Also, in the second set of examples:
function things(int $i, float $f, Point ...$points) { ... }
// Ex 13
$c = things(...);
$c = fn(int $i, float $f, ...$args) => things(...[$i, $f, ...$args]);// Ex 14
$c = things(1, 3.14, ...);
$c = fn(...$args) => things(...[1, 3.14, ...$args]);What happens to the typing of the variadic parameter here? Why is it removed?
It would feel natural that the ... means "copy the rest of the parameters from
signature". Here it seems it sometimes mean that, and sometimes mean "accept an
additional variadic parameter and pass it along".
Internally placeholders do mean the former. A trailing variadic, though, can accept extra arguments of potentially not pre-defined types, so it sort of straddles the line. Variadics make things weird. :-) (Dating from PHP 5.6.) In the majority case, though, thinking of them as "copy the rest of the arguments" is accurate.
--Larry Garfield
Le Thu, 17 Jun 2021 08:37:23 -0500,
"Larry Garfield" larry@garfieldtech.com a écrit :
$c = stuff(...);
$c = fn(int $i, string $s, float $f, Point $p, int $m = 0)
=> stuff($i, $s, $f, $p, $m);$c = stuff(1, 'hi', 3.4, $point, 5, ...);
$c = fn(...$args) => stuff(1, 'hi', 3.4, $point, 5, ...$args);Why is there an additional variadic parameter in this one?
... means "zero or more". In this case, it means zero, that is, it creates a
closure that requires no arguments and will call the original function with
all of the provided values later. This is the "deferred function" use case
mentioned further down.
I still do not understand why there is an added variadic parameter when
using ... in stuff(1, 'hi', 3.4, $point, 5, ...); but not when using it in
stuff(...);
What happens when we use stuff(1, 'hi', 3.4, $point, ...); ?
Also, in the second set of examples:
function things(int $i, float $f, Point ...$points) { ... }
// Ex 13
$c = things(...);
$c = fn(int $i, float $f, ...$args) => things(...[$i, $f, ...$args]);// Ex 14
$c = things(1, 3.14, ...);
$c = fn(...$args) => things(...[1, 3.14, ...$args]);What happens to the typing of the variadic parameter here? Why is it
removed?It would feel natural that the ... means "copy the rest of the parameters
from signature". Here it seems it sometimes mean that, and sometimes mean
"accept an additional variadic parameter and pass it along".Internally placeholders do mean the former. A trailing variadic, though, can
accept extra arguments of potentially not pre-defined types, so it sort of
straddles the line. Variadics make things weird. :-) (Dating from PHP
5.6.) In the majority case, though, thinking of them as "copy the rest of
the arguments" is accurate.
I do not understand why Points ...$points becomes untyped ...$args when using
things(...), while when using stuff(...) earlier no typing was lost.
Côme
Le Thu, 17 Jun 2021 08:37:23 -0500,
"Larry Garfield" larry@garfieldtech.com a écrit :$c = stuff(...);
$c = fn(int $i, string $s, float $f, Point $p, int $m = 0)
=> stuff($i, $s, $f, $p, $m);$c = stuff(1, 'hi', 3.4, $point, 5, ...);
$c = fn(...$args) => stuff(1, 'hi', 3.4, $point, 5, ...$args);Why is there an additional variadic parameter in this one?
... means "zero or more". In this case, it means zero, that is, it creates a
closure that requires no arguments and will call the original function with
all of the provided values later. This is the "deferred function" use case
mentioned further down.I still do not understand why there is an added variadic parameter when
using ... in stuff(1, 'hi', 3.4, $point, 5, ...); but not when using it in
stuff(...);
What happens when we use stuff(1, 'hi', 3.4, $point, ...); ?Also, in the second set of examples:
function things(int $i, float $f, Point ...$points) { ... }
// Ex 13
$c = things(...);
$c = fn(int $i, float $f, ...$args) => things(...[$i, $f, ...$args]);// Ex 14
$c = things(1, 3.14, ...);
$c = fn(...$args) => things(...[1, 3.14, ...$args]);What happens to the typing of the variadic parameter here? Why is it
removed?It would feel natural that the ... means "copy the rest of the parameters
from signature". Here it seems it sometimes mean that, and sometimes mean
"accept an additional variadic parameter and pass it along".Internally placeholders do mean the former. A trailing variadic, though, can
accept extra arguments of potentially not pre-defined types, so it sort of
straddles the line. Variadics make things weird. :-) (Dating from PHP
5.6.) In the majority case, though, thinking of them as "copy the rest of
the arguments" is accurate.I do not understand why Points ...$points becomes untyped ...$args when using
things(...), while when using stuff(...) earlier no typing was lost.
The type information is not lost. The examples are not exact equivalents, but approximate equivalents. Joe confirmed that the closure that's generated really does retain the type information:
krakjoe@Fiji:/opt/src/php-src$ cat wat.php
<?php
function things(int $i, float $f, Point ...$points) { }
$c = things(...);
echo (string) new ReflectionFunction($c);
krakjoe@Fiji:/opt/src/php-src$ sapi/cli/php wat.php
Function [ <user> partial function things ] {
@@ /opt/src/php-src/wat.php 4 - 4
- Parameters [3] {
Parameter #0 [ <optional> int $i ]
Parameter #1 [ <optional> float $f ]
Parameter #2 [ <optional> Point ...$points ]
}
}
--Larry Garfield
Le Wed, 16 Jun 2021 11:16:28 -0500,
"Larry Garfield" larry@garfieldtech.com a écrit :
Hi folks. The vote for the Partial Function Application RFC is now open, and
will run until 30 June.
From the RFC:
The ? character was chosen for the placeholder largely because it was
unambiguous and easy to implement. Prior, similar RFCs (such as the original
Pipe Operator proposal from several years ago) used the $$ (lovingly called
T_BLING) sigil instead. So far no compelling argument has been provided for
changing the character, so the RFC is sticking with ?.
The main argument for $$ is to be able to have partial methods with $$->, this
should be stated in this paragraph.
Côme
Le Wed, 16 Jun 2021 11:16:28 -0500,
"Larry Garfield" larry@garfieldtech.com a écrit :Hi folks. The vote for the Partial Function Application RFC is now open, and
will run until 30 June.From the RFC:
The ? character was chosen for the placeholder largely because it was
unambiguous and easy to implement. Prior, similar RFCs (such as the original
Pipe Operator proposal from several years ago) used the $$ (lovingly called
T_BLING) sigil instead. So far no compelling argument has been provided for
changing the character, so the RFC is sticking with ?.The main argument for $$ is to be able to have partial methods with $$->, this
should be stated in this paragraph.
That's not something that was ever brought up in the discussion.
--Larry Garfield
Le Thu, 17 Jun 2021 08:30:43 -0500,
"Larry Garfield" larry@garfieldtech.com a écrit :
The ? character was chosen for the placeholder largely because it was
unambiguous and easy to implement. Prior, similar RFCs (such as the
original Pipe Operator proposal from several years ago) used the $$
(lovingly called T_BLING) sigil instead. So far no compelling argument
has been provided for changing the character, so the RFC is sticking
with ?.The main argument for $$ is to be able to have partial methods with $$->,
this should be stated in this paragraph.That's not something that was ever brought up in the discussion.
Finally found where I read that, it’s in an other RFC:
https://wiki.php.net/rfc/first_class_callable_syntax#partial_function_application
Côme
On Tue, Jun 29, 2021 at 11:04 AM Côme Chilliet <
come.chilliet@fusiondirectory.org> wrote:
Le Thu, 17 Jun 2021 08:30:43 -0500,
"Larry Garfield" larry@garfieldtech.com a écrit :The ? character was chosen for the placeholder largely because it was
unambiguous and easy to implement. Prior, similar RFCs (such as the
original Pipe Operator proposal from several years ago) used the $$
(lovingly called T_BLING) sigil instead. So far no compelling
argument
has been provided for changing the character, so the RFC is sticking
with ?.The main argument for $$ is to be able to have partial methods with
$$->,
this should be stated in this paragraph.That's not something that was ever brought up in the discussion.
Finally found where I read that, it’s in an other RFC:
https://wiki.php.net/rfc/first_class_callable_syntax#partial_function_application
For the record, Larry replied on this subject:
https://externals.io/message/114770#114785 (second part).
Note that for $$->foo(/*whatever*/)
the signature couldn't be extracted
(because the class of $$ is unknown).
Regards,
--
Guilliam Xavier
On Wed, Jun 16, 2021 at 6:17 PM Larry Garfield larry@garfieldtech.com
wrote:
Hi folks. The vote for the Partial Function Application RFC is now open,
and will run until 30 June.https://wiki.php.net/rfc/partial_function_application
Of particular note, a few people had asked about using ...? instead of ...
for the variadic placeholder. In the end we decided not to explore that,
as Nikita explained off-list it was actually more confusing, not less, as
it would suggest "placeholder for a variadic" rather than "a placeholder
that is variadic." Otherwise, it's just more typing. The syntax choices
section of the RFC has been updated accordingly.
A couple of notes on the content (or non-content) of the RFC:
-
The behavior of nullsafe calls with PFA has been brought up in the
discussion, but is not mentioned in the RFC. For reference, $foo?->bar(?)
is the same as $foo !== null ? $foo->bar(?) : null. I don't think the
behavior is particularly unreasonable, but I also think it's not
particularly useful and may be surprising (in that there is a plausible
alternative behavior). I think you may have been better off forbidding that
case. -
The behavior of parameter names / reflection with regard to variadic
parameters is very odd. For function test(...$args) and test(?, ?, ?) you
get back a function that nominally has three parameters with the name
$args. Parameter names in PHP are generally required to be unique, and of
course this also has implications for named arguments, for example this
works, while it probably shouldn't:
https://3v4l.org/cQITD/rfc#focus=rfc.partials To be honest, I'm not sure
what the right way to handle this is, but I don't think this is it. A
possibility would be to bring back the concept of name-less parameters we
had prior to PHP 8 (for internal functions only), or possibly to make the
signature less precise by simply retaining an ...$args parameter, and just
making the enforcement of "at least three parameters" an implementation
detail. The latter seems like the best option. -
The RFC doesn't specify how PFA interacts with strict types. If I create
a partially-applied function in strict_types=1 file and call it in a
strict_types=0 file, what happens? Will it use strict_types=0 semantics,
including for arguments that were bound in the strict_types=1 file? -
It's worth noting that the "new Foo(?)" syntax will create and destroy a
Foo object as part of creating the partial (not just a call to the
partial). I've mostly convinced myself that this is probably harmless. It
would have interacted negatively with an earlier version of
https://wiki.php.net/rfc/new_in_initializers, but I think the problem there
was not on the side of partials.
In any case, I'm voting no on this one: While PFA is simple on a conceptual
level, the actual proposal is complex and has lots of tricky edge cases.
Especially once you take a look at the implementation. I'm not convinced
that PFA in its full generality is justified for inclusion in PHP.
Regards,
Nikita
Den 2021-06-18 kl. 16:08, skrev Nikita Popov:
On Wed, Jun 16, 2021 at 6:17 PM Larry Garfield larry@garfieldtech.com
wrote:Hi folks. The vote for the Partial Function Application RFC is now open,
and will run until 30 June.https://wiki.php.net/rfc/partial_function_application
Of particular note, a few people had asked about using ...? instead of ...
for the variadic placeholder. In the end we decided not to explore that,
as Nikita explained off-list it was actually more confusing, not less, as
it would suggest "placeholder for a variadic" rather than "a placeholder
that is variadic." Otherwise, it's just more typing. The syntax choices
section of the RFC has been updated accordingly.A couple of notes on the content (or non-content) of the RFC:
The behavior of nullsafe calls with PFA has been brought up in the
discussion, but is not mentioned in the RFC. For reference, $foo?->bar(?)
is the same as $foo !== null ? $foo->bar(?) : null. I don't think the
behavior is particularly unreasonable, but I also think it's not
particularly useful and may be surprising (in that there is a plausible
alternative behavior). I think you may have been better off forbidding that
case.The behavior of parameter names / reflection with regard to variadic
parameters is very odd. For function test(...$args) and test(?, ?, ?) you
get back a function that nominally has three parameters with the name
$args. Parameter names in PHP are generally required to be unique, and of
course this also has implications for named arguments, for example this
works, while it probably shouldn't:
https://3v4l.org/cQITD/rfc#focus=rfc.partials To be honest, I'm not sure
what the right way to handle this is, but I don't think this is it. A
possibility would be to bring back the concept of name-less parameters we
had prior to PHP 8 (for internal functions only), or possibly to make the
signature less precise by simply retaining an ...$args parameter, and just
making the enforcement of "at least three parameters" an implementation
detail. The latter seems like the best option.The RFC doesn't specify how PFA interacts with strict types. If I create
a partially-applied function in strict_types=1 file and call it in a
strict_types=0 file, what happens? Will it use strict_types=0 semantics,
including for arguments that were bound in the strict_types=1 file?It's worth noting that the "new Foo(?)" syntax will create and destroy a
Foo object as part of creating the partial (not just a call to the
partial). I've mostly convinced myself that this is probably harmless. It
would have interacted negatively with an earlier version of
https://wiki.php.net/rfc/new_in_initializers, but I think the problem there
was not on the side of partials.In any case, I'm voting no on this one: While PFA is simple on a conceptual
level, the actual proposal is complex and has lots of tricky edge cases.
Especially once you take a look at the implementation. I'm not convinced
that PFA in its full generality is justified for inclusion in PHP.Regards,
Nikita
Would you look on this feature in a different light if the above
concerns about strict types and nullsafe calls could be clarified /
solved? Or is it about the implementation with it's complexity and
tricky edge cases?
I myself think one should take into account that this is a feature
that would make PHP stand out even more. Not being a follower of
other languages here :-)
Regards //Björn L
I'd like to note a couple of things ...
The behaviour of nullsafe and strict types being unspecified in the RFC
would allow us to solve those problems later.
The behaviour of strict types right now is objectively wrong, the partial
takes strictness from the application site, so as Nikita already knew when
he asked the question; calls from a non-strict file will not behave as you
expect.
With regard to the complexity in the implementation: I think it's important
to understand that the complexity of the implementation is a product of the
semantics we landed on during discussion.
The first implementation where we only had ? was technically simpler, but
not intuitive from a user perspective.
Now we have semantics that are easy to understand, that you can communicate
in a few lines. But the implementation is necessarily complicated as a
result of those semantics.
We also have to remember that this is actually some kind of middle ground,
it's not the most complicated version of partial application we could have
- because that most complicated version would also include support for
re-ordering parameters (named placeholders), and nor is it the simplest
which offloaded a lot of (cognitive) overhead onto the programmer.
The question is not can we simplify the implementation, the question is
rather, is the necessary complexity of an implementation with the kind of
semantics that are desirable justified.
Cheers
Joe
On Mon, 21 Jun 2021 at 16:26, Björn Larsson via internals <
internals@lists.php.net> wrote:
Den 2021-06-18 kl. 16:08, skrev Nikita Popov:
On Wed, Jun 16, 2021 at 6:17 PM Larry Garfield larry@garfieldtech.com
wrote:Hi folks. The vote for the Partial Function Application RFC is now
open,
and will run until 30 June.https://wiki.php.net/rfc/partial_function_application
Of particular note, a few people had asked about using ...? instead of
...
for the variadic placeholder. In the end we decided not to explore
that,
as Nikita explained off-list it was actually more confusing, not less,
as
it would suggest "placeholder for a variadic" rather than "a placeholder
that is variadic." Otherwise, it's just more typing. The syntax
choices
section of the RFC has been updated accordingly.A couple of notes on the content (or non-content) of the RFC:
The behavior of nullsafe calls with PFA has been brought up in the
discussion, but is not mentioned in the RFC. For reference, $foo?->bar(?)
is the same as $foo !== null ? $foo->bar(?) : null. I don't think the
behavior is particularly unreasonable, but I also think it's not
particularly useful and may be surprising (in that there is a plausible
alternative behavior). I think you may have been better off forbidding
that
case.The behavior of parameter names / reflection with regard to variadic
parameters is very odd. For function test(...$args) and test(?, ?, ?) you
get back a function that nominally has three parameters with the name
$args. Parameter names in PHP are generally required to be unique, and of
course this also has implications for named arguments, for example this
works, while it probably shouldn't:
https://3v4l.org/cQITD/rfc#focus=rfc.partials To be honest, I'm not sure
what the right way to handle this is, but I don't think this is it. A
possibility would be to bring back the concept of name-less parameters we
had prior to PHP 8 (for internal functions only), or possibly to make the
signature less precise by simply retaining an ...$args parameter, and
just
making the enforcement of "at least three parameters" an implementation
detail. The latter seems like the best option.The RFC doesn't specify how PFA interacts with strict types. If I
create
a partially-applied function in strict_types=1 file and call it in a
strict_types=0 file, what happens? Will it use strict_types=0 semantics,
including for arguments that were bound in the strict_types=1 file?It's worth noting that the "new Foo(?)" syntax will create and destroy
a
Foo object as part of creating the partial (not just a call to the
partial). I've mostly convinced myself that this is probably harmless.
It
would have interacted negatively with an earlier version of
https://wiki.php.net/rfc/new_in_initializers, but I think the problem
there
was not on the side of partials.In any case, I'm voting no on this one: While PFA is simple on a
conceptual
level, the actual proposal is complex and has lots of tricky edge cases.
Especially once you take a look at the implementation. I'm not convinced
that PFA in its full generality is justified for inclusion in PHP.Regards,
NikitaWould you look on this feature in a different light if the above
concerns about strict types and nullsafe calls could be clarified /
solved? Or is it about the implementation with it's complexity and
tricky edge cases?I myself think one should take into account that this is a feature
that would make PHP stand out even more. Not being a follower of
other languages here :-)Regards //Björn L
--
To unsubscribe, visit: https://www.php.net/unsub.php
Hi and thanks for the clarification!
So if I get it right, by not addressing null safe calls and strict types
now we can address it later when we know a little bit more, which btw is
not the first time it's done. And the feature proposed requires a non
trivial implementation.
I think it should be noted that this is a feature where PHP is in the
forefront of language development, not a follower.
Of course it requires some afterthought, which I think the RFC fulfils
giving a broad explanation on why it is like it is. Maybe a bit weak on
the use cases, besides Pipe operator that would benefit from this feature.
So I hope it passes, +1 from me (not having a vote though).
Regards //Björn L
Den 2021-06-21 kl. 18:27, skrev Joe Watkins:
I'd like to note a couple of things ...
The behaviour of nullsafe and strict types being unspecified in the
RFC would allow us to solve those problems later.The behaviour of strict types right now is objectively wrong, the
partial takes strictness from the application site, so as Nikita
already knew when he asked the question; calls from a non-strict file
will not behave as you expect.With regard to the complexity in the implementation: I think it's
important to understand that the complexity of the implementation is a
product of the semantics we landed on during discussion.The first implementation where we only had ? was technically simpler,
but not intuitive from a user perspective.Now we have semantics that are easy to understand, that you can
communicate in a few lines. But the implementation is necessarily
complicated as a result of those semantics.We also have to remember that this is actually some kind of middle
ground, it's not the most complicated version of partial application
we could have - because that most complicated version would also
include support for re-ordering parameters (named placeholders), and
nor is it the simplest which offloaded a lot of (cognitive) overhead
onto the programmer.The question is not can we simplify the implementation, the question
is rather, is the necessary complexity of an implementation with the
kind of semantics that are desirable justified.Cheers
JoeOn Mon, 21 Jun 2021 at 16:26, Björn Larsson via internals
<internals@lists.php.net mailto:internals@lists.php.net> wrote:Den 2021-06-18 kl. 16:08, skrev Nikita Popov: > On Wed, Jun 16, 2021 at 6:17 PM Larry Garfield <larry@garfieldtech.com <mailto:larry@garfieldtech.com>> > wrote: > >> Hi folks. The vote for the Partial Function Application RFC is now open, >> and will run until 30 June. >> >> https://wiki.php.net/rfc/partial_function_application <https://wiki.php.net/rfc/partial_function_application> >> >> Of particular note, a few people had asked about using ...? instead of ... >> for the variadic placeholder. In the end we decided not to explore that, >> as Nikita explained off-list it was actually more confusing, not less, as >> it would suggest "placeholder for a variadic" rather than "a placeholder >> that is variadic." Otherwise, it's just more typing. The syntax choices >> section of the RFC has been updated accordingly. >> > > A couple of notes on the content (or non-content) of the RFC: > > * The behavior of nullsafe calls with PFA has been brought up in the > discussion, but is not mentioned in the RFC. For reference, $foo?->bar(?) > is the same as $foo !== null ? $foo->bar(?) : null. I don't think the > behavior is particularly unreasonable, but I also think it's not > particularly useful and may be surprising (in that there is a plausible > alternative behavior). I think you may have been better off forbidding that > case. > > * The behavior of parameter names / reflection with regard to variadic > parameters is very odd. For function test(...$args) and test(?, ?, ?) you > get back a function that nominally has three parameters with the name > $args. Parameter names in PHP are generally required to be unique, and of > course this also has implications for named arguments, for example this > works, while it probably shouldn't: > https://3v4l.org/cQITD/rfc#focus=rfc.partials <https://3v4l.org/cQITD/rfc#focus=rfc.partials> To be honest, I'm not sure > what the right way to handle this is, but I don't think this is it. A > possibility would be to bring back the concept of name-less parameters we > had prior to PHP 8 (for internal functions only), or possibly to make the > signature less precise by simply retaining an ...$args parameter, and just > making the enforcement of "at least three parameters" an implementation > detail. The latter seems like the best option. > > * The RFC doesn't specify how PFA interacts with strict types. If I create > a partially-applied function in strict_types=1 file and call it in a > strict_types=0 file, what happens? Will it use strict_types=0 semantics, > including for arguments that were bound in the strict_types=1 file? > > * It's worth noting that the "new Foo(?)" syntax will create and destroy a > Foo object as part of creating the partial (not just a call to the > partial). I've mostly convinced myself that this is *probably* harmless. It > would have interacted negatively with an earlier version of > https://wiki.php.net/rfc/new_in_initializers <https://wiki.php.net/rfc/new_in_initializers>, but I think the problem there > was not on the side of partials. > > In any case, I'm voting no on this one: While PFA is simple on a conceptual > level, the actual proposal is complex and has lots of tricky edge cases. > Especially once you take a look at the implementation. I'm not convinced > that PFA in its full generality is justified for inclusion in PHP. > > Regards, > Nikita > Would you look on this feature in a different light if the above concerns about strict types and nullsafe calls could be clarified / solved? Or is it about the implementation with it's complexity and tricky edge cases? I myself think one should take into account that this is a feature that would make PHP stand out even more. Not being a follower of other languages here :-) Regards //Björn L -- To unsubscribe, visit: https://www.php.net/unsub.php <https://www.php.net/unsub.php
On Mon, Jun 21, 2021 at 4:26 PM Björn Larsson bjorn.x.larsson@telia.com
wrote:
Den 2021-06-18 kl. 16:08, skrev Nikita Popov:
On Wed, Jun 16, 2021 at 6:17 PM Larry Garfield larry@garfieldtech.com
wrote:Hi folks. The vote for the Partial Function Application RFC is now
open,
and will run until 30 June.https://wiki.php.net/rfc/partial_function_application
Of particular note, a few people had asked about using ...? instead of
...
for the variadic placeholder. In the end we decided not to explore
that,
as Nikita explained off-list it was actually more confusing, not less,
as
it would suggest "placeholder for a variadic" rather than "a placeholder
that is variadic." Otherwise, it's just more typing. The syntax
choices
section of the RFC has been updated accordingly.A couple of notes on the content (or non-content) of the RFC:
The behavior of nullsafe calls with PFA has been brought up in the
discussion, but is not mentioned in the RFC. For reference, $foo?->bar(?)
is the same as $foo !== null ? $foo->bar(?) : null. I don't think the
behavior is particularly unreasonable, but I also think it's not
particularly useful and may be surprising (in that there is a plausible
alternative behavior). I think you may have been better off forbidding
that
case.The behavior of parameter names / reflection with regard to variadic
parameters is very odd. For function test(...$args) and test(?, ?, ?) you
get back a function that nominally has three parameters with the name
$args. Parameter names in PHP are generally required to be unique, and of
course this also has implications for named arguments, for example this
works, while it probably shouldn't:
https://3v4l.org/cQITD/rfc#focus=rfc.partials To be honest, I'm not sure
what the right way to handle this is, but I don't think this is it. A
possibility would be to bring back the concept of name-less parameters we
had prior to PHP 8 (for internal functions only), or possibly to make the
signature less precise by simply retaining an ...$args parameter, and
just
making the enforcement of "at least three parameters" an implementation
detail. The latter seems like the best option.The RFC doesn't specify how PFA interacts with strict types. If I
create
a partially-applied function in strict_types=1 file and call it in a
strict_types=0 file, what happens? Will it use strict_types=0 semantics,
including for arguments that were bound in the strict_types=1 file?It's worth noting that the "new Foo(?)" syntax will create and destroy
a
Foo object as part of creating the partial (not just a call to the
partial). I've mostly convinced myself that this is probably harmless.
It
would have interacted negatively with an earlier version of
https://wiki.php.net/rfc/new_in_initializers, but I think the problem
there
was not on the side of partials.In any case, I'm voting no on this one: While PFA is simple on a
conceptual
level, the actual proposal is complex and has lots of tricky edge cases.
Especially once you take a look at the implementation. I'm not convinced
that PFA in its full generality is justified for inclusion in PHP.Regards,
NikitaWould you look on this feature in a different light if the above
concerns about strict types and nullsafe calls could be clarified /
solved? Or is it about the implementation with it's complexity and
tricky edge cases?
These were just some notes on implementation details, they don't really
impact my overall opinion of the RFC. I should also say that I'm not
strongly opposed here, I'm just not convinced this is worthwhile :) The
complexity of the feature would be rather easy to overlook if I felt the
functionality was important.
I myself think one should take into account that this is a feature
that would make PHP stand out even more. Not being a follower of
other languages here :-)
Heh, it's the other way around for me: This just makes me more
apprehensive. Is there some special property of PHP that makes this feature
more relevant to us than other languages? All other mainstream languages do
well without this feature, so why do we need it?
Regards,
Nikita
These were just some notes on implementation details, they don't really
impact my overall opinion of the RFC. I should also say that I'm not
strongly opposed here, I'm just not convinced this is worthwhile :) The
complexity of the feature would be rather easy to overlook if I felt the
functionality was important.I myself think one should take into account that this is a feature
that would make PHP stand out even more. Not being a follower of
other languages here :-)Heh, it's the other way around for me: This just makes me more
apprehensive. Is there some special property of PHP that makes this feature
more relevant to us than other languages? All other mainstream languages do
well without this feature, so why do we need it?Regards,
Nikita
It depends what you mean by mainstream.
Ruby has a left-to-right-only version with an ugly syntax.
I just discovered there's a 3rd party macro for Rust that... looks an awful lot like this RFC:
https://docs.rs/partial_application/0.2.0/partial_application/
(I didn't spot it before because it's not part of the base language.)
I didn't think to look for R before, but apparently there's some kind of support there? (I know nothing beyond what this page has.) https://purrr.tidyverse.org/reference/partial.html
Most functional languages have some version of it, although generally left-to-right only. Which doesn't work when most of our standard lib was built without that in mind, so parameter order is not really convenient in most cases.
Javascript doesn't have it natively, but there are 3rd party libraries that try to do it. Python is the same. There are also existing 3rd party libraries to do partial application in PHP, but they're slow and clunky and no one markets them. :-)
Also, with only two exceptions (Rust and Go), most "mainstream" languages were developed long before the current trend of integrating functional features into more languages. (Rust has some solid functional features. Go actively avoids features as a design choice.)
So yes, this RFC would give PHP a more robust and flexible version of PFA than most other widely-used languages. But that doesn't mean PFA is some obscure unknown feature that no one ever uses. It's a valid feature that has been creeping into non-FP-centric languages slower than many would like, but it's hardly fringe.
--Larry Garfield
Javascript doesn't have it natively, but there are 3rd party libraries
that try to do it.
There is a proposal to add it to the language:
https://github.com/tc39/proposal-partial-application
Peter
Den 2021-06-28 kl. 16:52, skrev Nikita Popov:
On Mon, Jun 21, 2021 at 4:26 PM Björn Larsson
<bjorn.x.larsson@telia.com mailto:bjorn.x.larsson@telia.com> wrote:Would you look on this feature in a different light if the above concerns about strict types and nullsafe calls could be clarified / solved? Or is it about the implementation with it's complexity and tricky edge cases?
These were just some notes on implementation details, they don't
really impact my overall opinion of the RFC. I should also say that
I'm not strongly opposed here, I'm just not convinced this is
worthwhile :) The complexity of the feature would be rather easy to
overlook if I felt the functionality was important.I myself think one should take into account that this is a feature that would make PHP stand out even more. Not being a follower of other languages here :-)
Heh, it's the other way around for me: This just makes me more
apprehensive. Is there some special property of PHP that makes this
feature more relevant to us than other languages? All other mainstream
languages do well without this feature, so why do we need it?Regards,
Nikita
Well, I think the weak spot in the RFC is the motivation why do we need it.
OTOH, Larry posted the "The case for partials and pipes in PHP":
https://peakd.com/hive-168588/@crell/the-case-for-partials-and-pipes-in-php
Two things caught my eye there, namely the Health check & HTTP pipeline
and also the Scalar thing. Think it would have been good if these had been
part of the discussion phase and also highlighted a little in the RFC
itself.
So do you think these are good motivations on why we need it?
Regards //Björn L
On Wed, Jun 16, 2021 at 6:17 PM Larry Garfield larry@garfieldtech.com
wrote:
Hi folks. The vote for the Partial Function Application RFC is now open,
and will run until 30 June.https://wiki.php.net/rfc/partial_function_application
Of particular note, a few people had asked about using ...? instead of ...
for the variadic placeholder. In the end we decided not to explore that,
as Nikita explained off-list it was actually more confusing, not less, as
it would suggest "placeholder for a variadic" rather than "a placeholder
that is variadic." Otherwise, it's just more typing. The syntax choices
section of the RFC has been updated accordingly.
I wanted to explain my no vote on this one.
The examples section shows how every use-case of partials can be done using
short functions and while this is often a lot more to type (especially if
you mirror the typehints), these extra symbols feel necessary from my POV
to make the code clear that creates a partial.
Especially the ... as "additional" arguments and its various interactions
with ? produce so many different ways of calling something, it feels
unnecessary to me to introduce this complexity to newbies that might come
across use of this functionality. Plus the additional edge cases of delayed
execution, non-support for named parameters. Its a lot to know to fully
understand this feature.
Given that the functional paradigm isn't widely spread in use across PHP
developers, i am not convinced that we should add more features in this
direction that increase the complexity of understanding the language by
that much. While one could argue that functional paradigm isn't
wide-spread, because these features are missing, it is my believe that the
majority of PHP developers would still rather prefer imperative coding.
As a thought experiment I tried to think of code in our codebase that we
could convert to PFA once we migrated to 8.1 and there just isn't that
much. This is very different to short functions, nullabilty operator and
other "glue" / sugar proposals that were added to the language lately,
which a lot of existing code benefits from and existing code could be
converted automatically to them using phpcs/phpcbf rules.
I also am wary of the future after this RFC, as it states it is the
launching pad to another attempt at the Pipe Operator, which also proposes
to do a thing (calling functions) in a completly new way that will be hard
for beginners. I hope we don't add both these features to keep the language
smaller in this aspect of how functions are called.
--
Larry Garfield
larry@garfieldtech.com--
To unsubscribe, visit: https://www.php.net/unsub.php
Le sam. 19 juin 2021 à 01:41, Benjamin Eberlei kontakt@beberlei.de a
écrit :
On Wed, Jun 16, 2021 at 6:17 PM Larry Garfield larry@garfieldtech.com
wrote:Hi folks. The vote for the Partial Function Application RFC is now open,
and will run until 30 June.https://wiki.php.net/rfc/partial_function_application
Of particular note, a few people had asked about using ...? instead of
...
for the variadic placeholder. In the end we decided not to explore that,
as Nikita explained off-list it was actually more confusing, not less, as
it would suggest "placeholder for a variadic" rather than "a placeholder
that is variadic." Otherwise, it's just more typing. The syntax choices
section of the RFC has been updated accordingly.I wanted to explain my no vote on this one.
The examples section shows how every use-case of partials can be done using
short functions and while this is often a lot more to type (especially if
you mirror the typehints), these extra symbols feel necessary from my POV
to make the code clear that creates a partial.Especially the ... as "additional" arguments and its various interactions
with ? produce so many different ways of calling something, it feels
unnecessary to me to introduce this complexity to newbies that might come
across use of this functionality. Plus the additional edge cases of delayed
execution, non-support for named parameters. Its a lot to know to fully
understand this feature.Given that the functional paradigm isn't widely spread in use across PHP
developers, i am not convinced that we should add more features in this
direction that increase the complexity of understanding the language by
that much. While one could argue that functional paradigm isn't
wide-spread, because these features are missing, it is my believe that the
majority of PHP developers would still rather prefer imperative coding.As a thought experiment I tried to think of code in our codebase that we
could convert to PFA once we migrated to 8.1 and there just isn't that
much. This is very different to short functions, nullabilty operator and
other "glue" / sugar proposals that were added to the language lately,
which a lot of existing code benefits from and existing code could be
converted automatically to them using phpcs/phpcbf rules.I also am wary of the future after this RFC, as it states it is the
launching pad to another attempt at the Pipe Operator, which also proposes
to do a thing (calling functions) in a completly new way that will be hard
for beginners. I hope we don't add both these features to keep the language
smaller in this aspect of how functions are called.
I second Benjamin's opinion, hence my choice of voting "no" as well.
Every new feature we add adds an extra layer of complexity in an
exponential way, next new features/syntax have to deal with existing ones.
The problem being solved with PFA, including how frequent it could be
useful in PHP's ecosystem, does not, IMHO, counterbalance with the
increased code complexity.
-Patrick
HI Larry Garfield,
Do you have a plan to further extend this rfc? I mean, what if one
could typecast place holders? Broadly speaking, what if one could
perform some operations, such as arithmetic, bitwise, and type cast as
said above?
$foo = bar((type) ?);
$foo = bar(? & 0xFF);
Best
Hamza Ahmad
Le sam. 19 juin 2021 à 01:41, Benjamin Eberlei kontakt@beberlei.de a
écrit :On Wed, Jun 16, 2021 at 6:17 PM Larry Garfield larry@garfieldtech.com
wrote:Hi folks. The vote for the Partial Function Application RFC is now
open,
and will run until 30 June.https://wiki.php.net/rfc/partial_function_application
Of particular note, a few people had asked about using ...? instead of
...
for the variadic placeholder. In the end we decided not to explore
that,
as Nikita explained off-list it was actually more confusing, not less,
as
it would suggest "placeholder for a variadic" rather than "a
placeholder
that is variadic." Otherwise, it's just more typing. The syntax
choices
section of the RFC has been updated accordingly.I wanted to explain my no vote on this one.
The examples section shows how every use-case of partials can be done
using
short functions and while this is often a lot more to type (especially if
you mirror the typehints), these extra symbols feel necessary from my POV
to make the code clear that creates a partial.Especially the ... as "additional" arguments and its various interactions
with ? produce so many different ways of calling something, it feels
unnecessary to me to introduce this complexity to newbies that might come
across use of this functionality. Plus the additional edge cases of
delayed
execution, non-support for named parameters. Its a lot to know to fully
understand this feature.Given that the functional paradigm isn't widely spread in use across PHP
developers, i am not convinced that we should add more features in this
direction that increase the complexity of understanding the language by
that much. While one could argue that functional paradigm isn't
wide-spread, because these features are missing, it is my believe that
the
majority of PHP developers would still rather prefer imperative coding.As a thought experiment I tried to think of code in our codebase that we
could convert to PFA once we migrated to 8.1 and there just isn't that
much. This is very different to short functions, nullabilty operator and
other "glue" / sugar proposals that were added to the language lately,
which a lot of existing code benefits from and existing code could be
converted automatically to them using phpcs/phpcbf rules.I also am wary of the future after this RFC, as it states it is the
launching pad to another attempt at the Pipe Operator, which also
proposes
to do a thing (calling functions) in a completly new way that will be
hard
for beginners. I hope we don't add both these features to keep the
language
smaller in this aspect of how functions are called.I second Benjamin's opinion, hence my choice of voting "no" as well.
Every new feature we add adds an extra layer of complexity in an
exponential way, next new features/syntax have to deal with existing ones.
The problem being solved with PFA, including how frequent it could be
useful in PHP's ecosystem, does not, IMHO, counterbalance with the
increased code complexity.-Patrick
HI Larry Garfield,
Do you have a plan to further extend this rfc? I mean, what if one
could typecast place holders? Broadly speaking, what if one could
perform some operations, such as arithmetic, bitwise, and type cast as
said above?
$foo = bar((type) ?);
$foo = bar(? & 0xFF);
Best
Hamza Ahmad
We have no plans to extend it in that fashion, no. The only follow up I have in mind myself is the pipes RFC. If you want to do inline processing like that on a function call, then I think you are better off using a short lambdas as you already can today.
--Larry Garfield
On Wed, Jun 16, 2021 at 6:17 PM Larry Garfield larry@garfieldtech.com
wrote:Hi folks. The vote for the Partial Function Application RFC is now open,
and will run until 30 June.I wanted to explain my no vote on this one.
The examples section shows how every use-case of partials can be done using
short functions and while this is often a lot more to type (especially if
you mirror the typehints), these extra symbols feel necessary from my POV
to make the code clear that creates a partial.Especially the ... as "additional" arguments and its various interactions
with ? produce so many different ways of calling something, it feels
unnecessary to me to introduce this complexity to newbies that might come
across use of this functionality. Plus the additional edge cases of delayed
execution, non-support for named parameters. Its a lot to know to fully
understand this feature.Given that the functional paradigm isn't widely spread in use across PHP
developers, i am not convinced that we should add more features in this
direction that increase the complexity of understanding the language by
that much. While one could argue that functional paradigm isn't
wide-spread, because these features are missing, it is my believe that the
majority of PHP developers would still rather prefer imperative coding.As a thought experiment I tried to think of code in our codebase that we
could convert to PFA once we migrated to 8.1 and there just isn't that
much. This is very different to short functions, nullabilty operator and
other "glue" / sugar proposals that were added to the language lately,
which a lot of existing code benefits from and existing code could be
converted automatically to them using phpcs/phpcbf rules.I also am wary of the future after this RFC, as it states it is the
launching pad to another attempt at the Pipe Operator, which also proposes
to do a thing (calling functions) in a completly new way that will be hard
for beginners.
Just to offer a counter perspective since the assertion was made that partial functions would be hard for beginners.
I believe beginners will have a harder time comprehending closures, and especially short closures, than partial functions. And especially for the use-cases which are likely to be more common, none of which are any more "functional" in nature than PHP already is. The use-cases I think will be more common? Calling any of the existing built-in PHP functions that accept a callable as a parameter.
I am no expert on beginners but I did teach beginning programmers in a classroom setting for a decade. One of the biggest stumbling blocks I have found for beginners is excessive syntax that looks complex. Many of the concepts themselves are less difficult for beginners to understand.
So, in my experience it will be easier for newbies to understand this, for example:
array_map( $this->sanitize_value(?), $values );
Rather that this:
array_map( fn($value) => $this->sanitize_value($value), $values );
The latter just has more sigils to grok than the former, and from what I've seen with newbies when you throw too many sigils at them they quickly move into a learned helpless state and think that it will be too complicated for them to understand.
Bottom line though, what I am saying about newbies is just my opinion and probably biased by my own personal sensibilities.
If we want to consider how beginners will grok new features we should probably find a way to solicit objective feedback from beginners to consider in RFCs. Otherwise I fear each of us may just be assuming that beginners have the same sensibilities as we do.
And where most of us would be still using strings for function callables, the benefit of PFA for non-beginners is they let us use symbols to aid refactoring, static analysis, IDE functionality, etc.:
array_map( intval(?), $values );
Rather than:
array_map( 'intval', $values );
Of course we could use this, but seriously how many of us are using the following structure rather than just passing the function name as a string?
array_map( fn($value) => intval($value), $values );
I also am wary of the future after this RFC, as it states it is the
launching pad to another attempt at the Pipe Operator, which also proposes
to do a thing (calling functions) in a completly new way that will be hard
for beginners. I hope we don't add both these features to keep the language
smaller in this aspect of how functions are called.
For the record, my gut tells me beginners will not grok the proposed pipe operator as easily as I think they will partial functions. But who actually knows for sure how newbies will comprehend pipes?
-Mike
Just to offer a counter perspective since the assertion was made that
partial functions would be hard for beginners.I believe beginners will have a harder time comprehending closures, and
especially short closures, than partial functions. And especially for
the use-cases which are likely to be more common, none of which are any
more "functional" in nature than PHP already is. The use-cases I think
will be more common? Calling any of the existing built-in PHP functions
that accept a callable as a parameter.I am no expert on beginners but I did teach beginning programmers in a
classroom setting for a decade. One of the biggest stumbling blocks I
have found for beginners is excessive syntax that looks complex. Many
of the concepts themselves are less difficult for beginners to
understand.So, in my experience it will be easier for newbies to understand this,
for example:array_map( $this->sanitize_value(?), $values );
Rather that this:
array_map( fn($value) => $this->sanitize_value($value), $values );
The latter just has more sigils to grok than the former, and from what
I've seen with newbies when you throw too many sigils at them they
quickly move into a learned helpless state and think that it will be
too complicated for them to understand.
Frankly, that's the impression I get as well.
Any time PHP developers are discussing "what newbies find easy," there's a very, very strong bias toward "newbies are writing procedural code like it's 1990" and anything more complex than that is "advanced and confusing." And it always seems to be said by people who either are themselves primarily procedural programmers or started off as such, years ago. That bias leaks into their thinking about "what newbies think."
The thing is, new developers don't think anything. There's nothing intrinsically more "natural" about procedural code vs functional code, or OOP code, or whatever other paradigm. They're all artificial as far as the brain is concerned. People who start off in an OOP language, and are taught OOP from the get-go, are just as confused by procedural code as someone who learned procedural is when viewing OOP for the first time. Same for people who start in FP languages.
To hold that functional concepts or OOP concepts or whatever are "more advanced" and "less newbie friendly" than procedural is to buy into the rather damaging elitism that some in FP or strictly OOP languages have; that they're somehow "higher order developers" because they write in LISP, or Clojure, or Haskell, or whatever. That is simply self-serving elitism, but it is really easy for those in more conventional languages to inadvertently buy into that elitism.
The trend in recent years has been very clearly toward multi-paradigm languages. Even the world's most widely used language today, Javascript, is now a procedural/OOP/functional hybrid. It has its warts along the way (as does PHP), but if anything, given the number of people who get their start in Javascript these days I wager they'd expect to have easy to use higher-order functions, because Javascript does. In Javascript they would just write a function name directly, but "Oh, I have to put (?) after it" is a very short jump.
In some ways, we're still playing catch up, and PFA is an important part of that catch up.
Let's not limit PHP's potential reach with new-to-PHP developers by acting like they're all still late-90s new-to-development. These days, odds are good they're Javascript developers looking to move server-side, and they'll already have exposure to many functional concepts even if they don't know them as such explicitly.
For them, the common, non-pathological cases of PFA should be readily obvious to read and understand.
--Larry Garfield
The thing is, new developers don't think anything. There's nothing intrinsically more "natural" about procedural code vs functional code, or OOP code, or whatever other paradigm. They're all artificial as far as the brain is concerned. People who start off in an OOP language, and are taught OOP from the get-go, are just as confused by procedural code as someone who learned procedural is when viewing OOP for the first time. Same for people who start in FP languages.
I mentored many part-time student programmers. I'm not sure why some
people use the excuse of explaining syntax and semantics to juniors
because all the newbies I worked with had no trouble learning syntax
and semantics. They struggled with good design, writing testable code,
etc -- very different issues than the technical understanding of
syntax and semantics. I think people shouldn't worry so much about
mentoring newbies about syntax. Surely you have enough faith in them
to learn new things or you wouldn't have hired them!
Anyway, the vote currently sits at 14 yes to 10 no. Not a big turnout;
still time for it to pass or garner more opposition.
Hi folks. The vote for the Partial Function Application RFC is now open,
and will run until 30 June.
I like. People have either experienced the need for this or they haven't.
Ask me a month ago and I would have said "pfft, waste of time and language
bloat" but I changed my mind recently after running into issues in
JavaScript and discovering I needed partial function application to fix it
cleanly (vs a mess of mixed function calls and closure-wrapped function
calls).
I am a little ambivalent as I do feel the RFC's complexity has grown - I
would be happy without the variadic placeholder being included if it's a
choice between no partial function application or placeholders only. But if
I don't want to use variadic placeholders, hey I can omit them from my code.
Peter
Hi folks. The vote for the Partial Function Application RFC is now
open, and will run until 30 June.https://wiki.php.net/rfc/partial_function_application
Of particular note, a few people had asked about using ...? instead of
... for the variadic placeholder. In the end we decided not to explore
that, as Nikita explained off-list it was actually more confusing, not
less, as it would suggest "placeholder for a variadic" rather than "a
placeholder that is variadic." Otherwise, it's just more typing. The
syntax choices section of the RFC has been updated accordingly.
Since some people still don't grok the use cases, I've written a blog post to make the case for them better than a detail-oriented RFC can.
https://peakd.com/hive-168588/@crell/the-case-for-partials-and-pipes-in-php
There has also been some positive Twitter chatter, as well as the level of +1s on that post (which is, I think, the highest of any PHP post I've had on there, ever), so I think the demand for it is definitely there in the ecosystem. It's just not people who frequent Internals. :-/
I'd say there are definitely people that want to use partials.
--Larry Garfield
Le 24 juin 2021 à 18:02, Larry Garfield larry@garfieldtech.com a écrit :
Hi folks. The vote for the Partial Function Application RFC is now
open, and will run until 30 June.https://wiki.php.net/rfc/partial_function_application
Of particular note, a few people had asked about using ...? instead of
... for the variadic placeholder. In the end we decided not to explore
that, as Nikita explained off-list it was actually more confusing, not
less, as it would suggest "placeholder for a variadic" rather than "a
placeholder that is variadic." Otherwise, it's just more typing. The
syntax choices section of the RFC has been updated accordingly.Since some people still don't grok the use cases, I've written a blog post to make the case for them better than a detail-oriented RFC can.
https://peakd.com/hive-168588/@crell/the-case-for-partials-and-pipes-in-php
There has also been some positive Twitter chatter, as well as the level of +1s on that post (which is, I think, the highest of any PHP post I've had on there, ever), so I think the demand for it is definitely there in the ecosystem. It's just not people who frequent Internals. :-/
I'd say there are definitely people that want to use partials.
--Larry Garfield
--
To unsubscribe, visit: https://www.php.net/unsub.php
Hi,
In the blog post, you are not fair when comparing:
Request::fromGlobals()
|> normalize_path(?)
|> oauth_check(?)
|> parse_body($dbconn, ?)
|> $resolver->resolveController(?)
|> controller_caller(?)
|> response_handler(?, $theme_system)
|> $add_cache_headers(?)
|> send_response(?)
;
with:
Request::fromGlobals()
|> fn(ServerRequestInterface $request): ServerRequestInterface => normalize_path($request)
|> fn(ServerRequestInterface $request): ServerRequestInterface => oauth_check($request)
|> fn(ServerRequestInterface $request): ServerRequestInterface => parse_body($dbconn, $request)
|> fn(ServerRequestInterface $request): ServerRequestInterface => $resolver->resolveController($request)
|> fn(ServerRequestInterface $request): ResponseInterface => controller_caller($request)
|> fn(ResponseInterface $response): ResponseInterface => response_handler($response, $theme_system)
|> fn(ResponseInterface $response): ResponseInterface => $add_cache_headers($response)
|> fn(ResponseInterface $response): ResponseInterface => send_response($response)
;
I would write it the following way:
Request::fromGlobals()
|> fn($_) => normalize_path($_)
|> fn($_) => oauth_check($_)
|> fn($_) => parse_body($dbconn, $_)
|> fn($_) => $resolver->resolveController($_)
|> fn($_) => controller_caller($_)
|> fn($_) => response_handler($_, $theme_system)
|> fn($_) => $add_cache_headers($_)
|> fn($_) => send_response($_)
;
The version with partials is still better as it has less grawlix, but the difference between the two is considerably reduced. Style can make a big difference in readability.
Also, without pipes or partials, it could be written as:
$_ = Request::fromGlobals();
$_ = normalize_path($_);
$_ = oauth_check($_);
$_ = parse_body($dbconn, $_);
$_ = $resolver->resolveController($_);
$_ = controller_caller($_);
$_ = response_handler($_, $theme_system);
$_ = $add_cache_headers($_);
send_response($_);
where my $_
s play the role of your ?
s.
(I still do find that pipes and partials would be nice additions, but it is not something that I am desperately craving after.)
—Claude
Le 24 juin 2021 à 18:02, Larry Garfield larry@garfieldtech.com a écrit :
Hi folks. The vote for the Partial Function Application RFC is now
open, and will run until 30 June.https://wiki.php.net/rfc/partial_function_application
Of particular note, a few people had asked about using ...? instead of
... for the variadic placeholder. In the end we decided not to explore
that, as Nikita explained off-list it was actually more confusing, not
less, as it would suggest "placeholder for a variadic" rather than "a
placeholder that is variadic." Otherwise, it's just more typing. The
syntax choices section of the RFC has been updated accordingly.Since some people still don't grok the use cases, I've written a blog post to make the case for them better than a detail-oriented RFC can.
https://peakd.com/hive-168588/@crell/the-case-for-partials-and-pipes-in-php
There has also been some positive Twitter chatter, as well as the level of +1s on that post (which is, I think, the highest of any PHP post I've had on there, ever), so I think the demand for it is definitely there in the ecosystem. It's just not people who frequent Internals. :-/
I'd say there are definitely people that want to use partials.
--Larry Garfield
--
To unsubscribe, visit: https://www.php.net/unsub.php
Hi,
In the blog post, you are not fair when comparing:
Request::fromGlobals() |> normalize_path(?) |> oauth_check(?) |> parse_body($dbconn, ?) |> $resolver->resolveController(?) |> controller_caller(?) |> response_handler(?, $theme_system) |> $add_cache_headers(?) |> send_response(?) ;
with:
Request::fromGlobals() |> fn(ServerRequestInterface $request): ServerRequestInterface => normalize_path($request) |> fn(ServerRequestInterface $request): ServerRequestInterface => oauth_check($request) |> fn(ServerRequestInterface $request): ServerRequestInterface => parse_body($dbconn, $request) |> fn(ServerRequestInterface $request): ServerRequestInterface => $resolver->resolveController($request) |> fn(ServerRequestInterface $request): ResponseInterface => controller_caller($request) |> fn(ResponseInterface $response): ResponseInterface => response_handler($response, $theme_system) |> fn(ResponseInterface $response): ResponseInterface => $add_cache_headers($response) |> fn(ResponseInterface $response): ResponseInterface => send_response($response) ;
I would write it the following way:
Request::fromGlobals() |> fn($_) => normalize_path($_) |> fn($_) => oauth_check($_) |> fn($_) => parse_body($dbconn, $_) |> fn($_) => $resolver->resolveController($_) |> fn($_) => controller_caller($_) |> fn($_) => response_handler($_, $theme_system) |> fn($_) => $add_cache_headers($_) |> fn($_) => send_response($_) ;
The version with partials is still better as it has less grawlix, but the difference between the two is considerably reduced. Style can make a big difference in readability.
Also, without pipes or partials, it could be written as:
$_ = Request::fromGlobals(); $_ = normalize_path($_); $_ = oauth_check($_); $_ = parse_body($dbconn, $_); $_ = $resolver->resolveController($_); $_ = controller_caller($_); $_ = response_handler($_, $theme_system); $_ = $add_cache_headers($_); send_response($_);
where my
$_
s play the role of your?
s.(I still do find that pipes and partials would be nice additions, but it is not something that I am desperately craving after.)
—Claude
Ah, but you've uncovered one of the benefits of partials -- they
propagate type information. Of course, in this case you would hit an
error immediately so it wouldn't make that much of a difference, but
there are cases where it would matter, such as when being used in
callbacks to array_map
and such.
Hi folks. The vote for the Partial Function Application RFC is now
open, and will run until 30 June.https://wiki.php.net/rfc/partial_function_application
Of particular note, a few people had asked about using ...? instead of
... for the variadic placeholder. In the end we decided not to explore
that, as Nikita explained off-list it was actually more confusing, not
less, as it would suggest "placeholder for a variadic" rather than "a
placeholder that is variadic." Otherwise, it's just more typing. The
syntax choices section of the RFC has been updated accordingly.Since some people still don't grok the use cases, I've written a blog post
to make the case for them better than a detail-oriented RFC can.https://peakd.com/hive-168588/@crell/the-case-for-partials-and-pipes-in-php
There has also been some positive Twitter chatter, as well as the level of
+1s on that post (which is, I think, the highest of any PHP post I've had
on there, ever), so I think the demand for it is definitely there in the
ecosystem. It's just not people who frequent Internals. :-/I'd say there are definitely people that want to use partials.
--Larry Garfield
--
To unsubscribe, visit: https://www.php.net/unsub.php
Out of curiosity, what would it take to implement function aliasing in PHP?
To enable a limited form of pipes, like foo |> bar
.
Olle
Hi folks. The vote for the Partial Function Application RFC is now
open, and will run until 30 June.https://wiki.php.net/rfc/partial_function_application
Of particular note, a few people had asked about using ...? instead of
... for the variadic placeholder. In the end we decided not to explore
that, as Nikita explained off-list it was actually more confusing, not
less, as it would suggest "placeholder for a variadic" rather than "a
placeholder that is variadic." Otherwise, it's just more typing. The
syntax choices section of the RFC has been updated accordingly.Since some people still don't grok the use cases, I've written a blog post
to make the case for them better than a detail-oriented RFC can.https://peakd.com/hive-168588/@crell/the-case-for-partials-and-pipes-in-php
There has also been some positive Twitter chatter, as well as the level of
+1s on that post (which is, I think, the highest of any PHP post I've had
on there, ever), so I think the demand for it is definitely there in the
ecosystem. It's just not people who frequent Internals. :-/I'd say there are definitely people that want to use partials.
--Larry Garfield
--
To unsubscribe, visit: https://www.php.net/unsub.php
Out of curiosity, what would it take to implement function aliasing in PHP?
To enable a limited form of pipes, likefoo |> bar
.Olle
We probably could special case it for pipes; it's more of a matter if
we should. But, to do it generally so that things like
array_map(strlen, $arr)
work is not trivial. The main issue is that
different symbol types have separate "tables", if you will. The engine
decides to look in one bucket or another based on the syntax. In this
case, based on syntax the engine will look in the constant table for
strlen
, as strlen
in array_map(strlen, $arr)
is a constant
lookup by syntax.
If we want it to fall-back to looking in other tables, then we'd have
to deal with various challenges:
- We have to deal with symbol collisions that exist today somehow,
such as ifstrlen
exists both as a function and a constant, or if
$this->count
exists as both a property and a method. I would prefer
to do the simple thing and forbid collisions, but there are other
strategies. - How do we handle the fact that different symbol types behave
differently in namespaces when the symbol doesn't exist? - Also, how do we handle differences in case sensitivity between symbol types?
Personally, I think it's worth it to change all of these things,
because it could also give us function and constant autoloading. Of
course, we'd have to get 2/3 of voters to agree on solutions to these
things, which probably includes some backward-compatibility breaks so
that might be difficult. But, nobody has tried so maybe not.
On Mon, 28 Jun 2021, 18:49 Levi Morrison, levi.morrison@datadoghq.com
wrote:
On Mon, Jun 28, 2021 at 10:32 AM Olle Härstedt olleharstedt@gmail.com
wrote:On Thu, 24 Jun 2021, 18:02 Larry Garfield, larry@garfieldtech.com
wrote:Hi folks. The vote for the Partial Function Application RFC is now
open, and will run until 30 June.https://wiki.php.net/rfc/partial_function_application
Of particular note, a few people had asked about using ...? instead
of
... for the variadic placeholder. In the end we decided not to
explore
that, as Nikita explained off-list it was actually more confusing,
not
less, as it would suggest "placeholder for a variadic" rather than "a
placeholder that is variadic." Otherwise, it's just more typing.
The
syntax choices section of the RFC has been updated accordingly.Since some people still don't grok the use cases, I've written a blog
post
to make the case for them better than a detail-oriented RFC can.https://peakd.com/hive-168588/@crell/the-case-for-partials-and-pipes-in-php
There has also been some positive Twitter chatter, as well as the
level of
+1s on that post (which is, I think, the highest of any PHP post I've
had
on there, ever), so I think the demand for it is definitely there in
the
ecosystem. It's just not people who frequent Internals. :-/I'd say there are definitely people that want to use partials.
--Larry Garfield
--
To unsubscribe, visit: https://www.php.net/unsub.php
Out of curiosity, what would it take to implement function aliasing in
PHP?
To enable a limited form of pipes, likefoo |> bar
.Olle
We probably could special case it for pipes; it's more of a matter if
we should. But, to do it generally so that things like
array_map(strlen, $arr)
work is not trivial. The main issue is that
different symbol types have separate "tables", if you will. The engine
decides to look in one bucket or another based on the syntax. In this
case, based on syntax the engine will look in the constant table for
strlen
, asstrlen
inarray_map(strlen, $arr)
is a constant
lookup by syntax.If we want it to fall-back to looking in other tables, then we'd have
to deal with various challenges:
- We have to deal with symbol collisions that exist today somehow,
such as ifstrlen
exists both as a function and a constant, or if
$this->count
exists as both a property and a method. I would prefer
to do the simple thing and forbid collisions, but there are other
strategies.- How do we handle the fact that different symbol types behave
differently in namespaces when the symbol doesn't exist?- Also, how do we handle differences in case sensitivity between symbol
types?Personally, I think it's worth it to change all of these things,
because it could also give us function and constant autoloading. Of
course, we'd have to get 2/3 of voters to agree on solutions to these
things, which probably includes some backward-compatibility breaks so
that might be difficult. But, nobody has tried so maybe not.
Right. So you'd have to add a resolve sympol type routine, and if it
returns "this is a function/method", strlen would evaluate to be wrapped in
a lambda? Then the problem would be the overall performance cost of such a
routine, and to deal with collisions, as you said. Hm.
Well, couldn't another alternative be that pipe operator assumes a callable
it can wrap on its right side? This wouldn't allow the array map use case,
but it would allow others. A third alternative would be to type-cast to
callable, perhaps.
array_map((callable) strlen, $arr);
This would be a shorter version of manually writing out the wrapping
lambda. But there's already fn, so. No big benefit.
Olle
(Extracted from the "Pipe Operator, take 2" thread)
On Tue, Jun 29, 2021 at 12:54 AM Larry Garfield larry@garfieldtech.com
wrote:
Would a slimmed down version have more support? How about removing the
variadic operator, and let the user manually add the lambda for those
cases?I talked with Joe about this, and the answer is no. Most of the
complexity comes from the initial "this is a function call, oops no, it's a
partial call so we switch to doing that instead", which ends up interacting
with the engine in a lot of different places.
Are you saying that the implementation complexity is mainly due to chosing
a syntax that looks like a function call?
If yes, is it also the case for the "First-class callable syntax" RFC?
And does it mean that a different syntax (e.g. with a prefix operator)
would result in a simpler implementation?
Regards,
--
Guilliam Xavier
(Extracted from the "Pipe Operator, take 2" thread)
On Tue, Jun 29, 2021 at 12:54 AM Larry Garfield larry@garfieldtech.com
wrote:Would a slimmed down version have more support? How about removing the
variadic operator, and let the user manually add the lambda for those
cases?I talked with Joe about this, and the answer is no. Most of the
complexity comes from the initial "this is a function call, oops no, it's a
partial call so we switch to doing that instead", which ends up interacting
with the engine in a lot of different places.Are you saying that the implementation complexity is mainly due to chosing
a syntax that looks like a function call?
If yes, is it also the case for the "First-class callable syntax" RFC?
And does it mean that a different syntax (e.g. with a prefix operator)
would result in a simpler implementation?
From what I understand from Joe, most of the complexity comes from producing something that isn't a closure but shares the same interface as a closure (at least that's what it would be in PHP terms), which then requires lots of special handling throughout the engine. I don't fully understand it all myself, TBH.
I've been pondering if a completely different approach with a prefix symbol would be able to be less complex, and the simple answer is I have absolutely no idea. But we are running low on symbols...
--Larry Garfield
(Extracted from the "Pipe Operator, take 2" thread)
On Tue, Jun 29, 2021 at 12:54 AM Larry Garfield larry@garfieldtech.com
wrote:Would a slimmed down version have more support? How about removing the
variadic operator, and let the user manually add the lambda for those
cases?I talked with Joe about this, and the answer is no. Most of the
complexity comes from the initial "this is a function call, oops no, it's a
partial call so we switch to doing that instead", which ends up interacting
with the engine in a lot of different places.Are you saying that the implementation complexity is mainly due to chosing
a syntax that looks like a function call?
If yes, is it also the case for the "First-class callable syntax" RFC?
And does it mean that a different syntax (e.g. with a prefix operator)
would result in a simpler implementation?From what I understand from Joe, most of the complexity comes from
producing something that isn't a closure but shares the same interface
as a closure (at least that's what it would be in PHP terms), which
then requires lots of special handling throughout the engine. I don't
fully understand it all myself, TBH.I've been pondering if a completely different approach with a prefix
symbol would be able to be less complex, and the simple answer is I
have absolutely no idea. But we are running low on symbols...
Ah, I found the technical details that Joe gave me (right after I hit send, of course). Quoting Joe:
"the engine expects certain things to happen, and is designed and then optimized around those assumptions ... for example, a stream of INIT, SEND, DO_FCALL is not meant to be interrupted, the first fundamental change you have to make is making the engine aware that stream of INIT, SEND, + are not always followed by DO_FCALL "
So yes, it sounds like hooking into the function call process is where the complexity comes from. Which suggests that an approach that works using a different syntax that desugars to a closure would avoid that issue, but then we need a syntax that wouldn't be ambiguous, and that's getting harder and harder to find. (Nikita's first-class-callables RFC notes some of the issues with available symbols, and they're essentially the same for partials either way.) And I've been told that creating closures in the AST compiler is Hard(tm)...
--Larry Garfield
(Extracted from the "Pipe Operator, take 2" thread)
On Tue, Jun 29, 2021 at 12:54 AM Larry Garfield larry@garfieldtech.com
wrote:Would a slimmed down version have more support? How about removing the
variadic operator, and let the user manually add the lambda for those
cases?I talked with Joe about this, and the answer is no. Most of the
complexity comes from the initial "this is a function call, oops no, it's a
partial call so we switch to doing that instead", which ends up interacting
with the engine in a lot of different places.Are you saying that the implementation complexity is mainly due to chosing
a syntax that looks like a function call?
If yes, is it also the case for the "First-class callable syntax" RFC?
And does it mean that a different syntax (e.g. with a prefix operator)
would result in a simpler implementation?From what I understand from Joe, most of the complexity comes from
producing something that isn't a closure but shares the same interface
as a closure (at least that's what it would be in PHP terms), which
then requires lots of special handling throughout the engine. I don't
fully understand it all myself, TBH.I've been pondering if a completely different approach with a prefix
symbol would be able to be less complex, and the simple answer is I
have absolutely no idea. But we are running low on symbols...Ah, I found the technical details that Joe gave me (right after I hit send, of course). Quoting Joe:
"the engine expects certain things to happen, and is designed and then optimized around those assumptions ... for example, a stream of INIT, SEND, DO_FCALL is not meant to be interrupted, the first fundamental change you have to make is making the engine aware that stream of INIT, SEND, + are not always followed by DO_FCALL "
So yes, it sounds like hooking into the function call process is where the complexity comes from. Which suggests that an approach that works using a different syntax that desugars to a closure would avoid that issue, but then we need a syntax that wouldn't be ambiguous, and that's getting harder and harder to find. (Nikita's first-class-callables RFC notes some of the issues with available symbols, and they're essentially the same for partials either way.) And I've been told that creating closures in the AST compiler is Hard(tm)...
--Larry Garfield
Based on what you said, the syntax isn't really the issue. Rather, the
issue is assumptions about how function calls work at the opcode
level. Any implementation of only partially doing a function call
will have to deal with such things in some form. To a degree this is
inherent complexity.
Maybe separate opcodes for every piece of the call would be better in
that optimizers, etc, won't have expectations around the new opcodes
and we don't change assumptions about the existing opcodes? I doubt
that it would be much simpler, but I am curious to know.
On Tue, Jun 29, 2021 at 10:32 PM Levi Morrison via internals <
internals@lists.php.net> wrote:
On Tue, Jun 29, 2021 at 12:05 PM Larry Garfield larry@garfieldtech.com
wrote:(Extracted from the "Pipe Operator, take 2" thread)
On Tue, Jun 29, 2021 at 12:54 AM Larry Garfield <
larry@garfieldtech.com>
wrote:[...] Most of the
complexity comes from the initial "this is a function call, oops
no, it's a
partial call so we switch to doing that instead", which ends up
interacting
with the engine in a lot of different places. [...]Are you saying that the implementation complexity is mainly due to
chosing
a syntax that looks like a function call? [...]From what I understand from Joe, most of the complexity comes from
producing something that isn't a closure but shares the same interface
as a closure (at least that's what it would be in PHP terms), which
then requires lots of special handling throughout the engine. I don't
fully understand it all myself, TBH.I've been pondering if a completely different approach with a prefix
symbol would be able to be less complex, and the simple answer is I
have absolutely no idea. But we are running low on symbols...Ah, I found the technical details that Joe gave me (right after I hit
send, of course). Quoting Joe:"the engine expects certain things to happen, and is designed and then
optimized around those assumptions ... for example, a stream of INIT, SEND,
DO_FCALL is not meant to be interrupted, the first fundamental change you
have to make is making the engine aware that stream of INIT, SEND, + are
not always followed by DO_FCALL "So yes, it sounds like hooking into the function call process is where
the complexity comes from. Which suggests that an approach that works
using a different syntax that desugars to a closure would avoid that issue,
but then we need a syntax that wouldn't be ambiguous, and that's getting
harder and harder to find. (Nikita's first-class-callables RFC notes some
of the issues with available symbols, and they're essentially the same for
partials either way.) And I've been told that creating closures in the AST
compiler is Hard(tm)...Based on what you said, the syntax isn't really the issue. Rather, the
issue is assumptions about how function calls work at the opcode
level. Any implementation of only partially doing a function call
will have to deal with such things in some form. To a degree this is
inherent complexity.
Thanks for clarifications.
IIUC, whatever the syntax, any PFA implementation will need either to hook
into the function call process (current approach) or to create a closure
"from scratch" (which may be actually more complex);
and some degree of [implementation] complexity is conceptually inherent
anyway.
(FCC doesn't need to bind values so might have other options? maybe not...)
Maybe separate opcodes for every piece of the call would be better in
that optimizers, etc, won't have expectations around the new opcodes
and we don't change assumptions about the existing opcodes? I doubt
that it would be much simpler, but I am curious to know.
--
Guilliam Xavier
Hi folks. The vote for the Partial Function Application RFC is now
open, and will run until 30 June.https://wiki.php.net/rfc/partial_function_application
Of particular note, a few people had asked about using ...? instead of
... for the variadic placeholder. In the end we decided not to explore
that, as Nikita explained off-list it was actually more confusing, not
less, as it would suggest "placeholder for a variadic" rather than "a
placeholder that is variadic." Otherwise, it's just more typing. The
syntax choices section of the RFC has been updated accordingly.
The vote has now closed. The final result is:
Yes; 29
No: 20
Percentage: 59.1%
It has not passed. Thank you everyone for your involvement.
I'd like to bring this RFC back in the future in some form if either a less complex implementation or a stronger use case to justify the implementation can be found. That would be a topic for a different thread at a different time.
--Larry Garfield
2021-07-01 17:12 GMT+02:00, Larry Garfield larry@garfieldtech.com:
Hi folks. The vote for the Partial Function Application RFC is now
open, and will run until 30 June.https://wiki.php.net/rfc/partial_function_application
Of particular note, a few people had asked about using ...? instead of
... for the variadic placeholder. In the end we decided not to explore
that, as Nikita explained off-list it was actually more confusing, not
less, as it would suggest "placeholder for a variadic" rather than "a
placeholder that is variadic." Otherwise, it's just more typing. The
syntax choices section of the RFC has been updated accordingly.The vote has now closed. The final result is:
Yes; 29
No: 20
Percentage: 59.1%It has not passed. Thank you everyone for your involvement.
I'd like to bring this RFC back in the future in some form if either a less
complex implementation or a stronger use case to justify the implementation
can be found. That would be a topic for a different thread at a different
time.--Larry Garfield
Hi,
My personal impression is that the feedback loop between RFC authors
and voters seems a bit vague. Should the no-vote be split into "Yes,
but not like this", and "No, never"? Or maybe add a reason for the
no-vote? Like, too complex implementation, or weak use-case. I don't
know. Guessing should be reduced to a minimum, as should be wasted
effort.
I also believe the structure of the RFC itself could be more
disciplined, and collect pros and cons more clearly. Not this
particular RFC, but in general. I assume there's a scaffold being
used?
Olle