Re: [PHP-DEV] [RFC] Pipe Operator, take 2

2021-07-06 Thread Joe Watkins
Just to clarify,

I said it didn't look like it could be a pure AST implementation, and that
it looks like you may need one additional instruction.

It does look that way to me - if only to throw a sensible error
specifically for pipes but also because it makes the imposition of specific
behaviour for pipes a little easier, but it doesn't make it a super
complicated thing.

I also said I didn't know what the right answer was with regard to refs. I
still don't, although I lean towards blocking them at the moment having
spent a little more time looking at it.

I don't really think we've had long enough to have this conversation
properly.

Cheers
Joe

On Tue, 6 Jul 2021 at 19:05, Larry Garfield  wrote:

> On Mon, Jul 5, 2021, at 11:05 AM, Larry Garfield wrote:
> > On Sat, Jul 3, 2021, at 9:12 PM, Larry Garfield wrote:
> > > On Mon, Jun 7, 2021, at 2:00 PM, Larry Garfield wrote:
> > > > Hi folks. Me again.
> > > >
> > > > A year ago, I posted an RFC for a pipe operator, |>, aka function
> > > > concatenation.  At the time, the main thrust of the feedback was
> "cool,
> > > > like, but we need partial function application first so that the
> syntax
> > > > for callables isn't so crappy."
> > > >
> > > > The PFA RFC is winding down now and is looking quite good, so it's
> time
> > > > to revisit pipes.
> > > >
> > > > https://wiki.php.net/rfc/pipe-operator-v2
> > > >
> > > > Nothing radical has changed in the proposal since last year.  I have
> > > > updated it against the latest master.  I also updated the RFC to use
> > > > more examples that assume PFA, as the result is legit much nicer.  i
> > > > also tested it locally with a combined partials-and-pipes branch to
> > > > make sure they play nicely together, and they do.  (Yay!)  Assuming
> PFA
> > > > passes I will include those tests in the pipes branch before this
> one
> > > > goes to a vote.
> > >
> > > Hi again.
> > >
> > > With PFA being declined, I've again reworked the Pipes RFC.
> > >
> > > 1) It now does not use PFA in any examples, but it does use Nikita's
> > > first-class-callables RFC that looks like it's going to pass easily.
> > >
> > > 2) With major hand-holding from Levi Morrison and Joe Watkins, the
> > > implementation has shifted a bit.  It now evaluates left-to-right,
> > > always, whereas the previous version evaluated right-to-left.  That
> is,
> > > instead of $a |> $b |> $c desugaring into $c($b($a)), it now becomes
> > > effectively $tmp = $a; $tmp = $b($tmp); $tmp = $c($tmp);  That matters
> > > if $b or $c are function calls that return a callable, as they are
> then
> > > only called when the pipeline gets to that part of the expression.
> (If
> > > all the functions involved are pure functions, then it doesn't make a
> > > difference in practice.)
> > >
> > > 3) I included references to several existing PHP libraries that
> > > implement similar logic, in mostly complex and ugly ways.
> > >
> > > 4) Of note, Brent posted a Twitter poll last week about pipes, and the
> > > response was overwhelmingly in favor.
> > > (https://twitter.com/brendt_gd/status/1408271132650885123)  Naturally
> a
> > > Twitter poll is extremely unscientific, but I think between the
> > > existing libraries and the response there the answer to the question
> > > "is there actually a demand for this feature?" is unquestionably yes.
> > >
> > > 5) Examples have been reworked to be a bit prettier.
> > >
> > > 6) Added another language reference that has a pipe operator that
> works
> > > basically like described here. (OCaml)
> > >
> > > I am planning to take this version of the RFC to a vote on Monday or
> > > Tuesday, as Tuesday is the last day possible to start a vote for 8.1
> > > features.
> > >
> > > --Larry Garfield
> >
> > Based on feedback on the PR, I've updated the RFC to forbid functions
> > that pass or return by reference.  They're not really useful in pipes
> > at all, and were only supported before because the implementation
> > happened to allow it.
> >
> > The PR hasn't been updated for that yet, but I figure that's easy
> > enough to update post-vote if it passes.
>
> Sorry for the noise, but after some discussion with Joe it looks like
> blocking references in pipes is actually much harder than it sounded like,
> and would require a completely opcode based implementation rather than the
> completely AST-based implementation.  References on pipes are not really
> useful but in practice they don't hurt anything.  I've instead added more
> tests to validate that they behave "as expected" and noted that in the RFC
> instead.
>
> --Larry Garfield
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
>
>


Re: [PHP-DEV] [RFC] Pipe Operator, take 2

2021-07-06 Thread Larry Garfield
On Mon, Jul 5, 2021, at 11:05 AM, Larry Garfield wrote:
> On Sat, Jul 3, 2021, at 9:12 PM, Larry Garfield wrote:
> > On Mon, Jun 7, 2021, at 2:00 PM, Larry Garfield wrote:
> > > Hi folks. Me again.
> > > 
> > > A year ago, I posted an RFC for a pipe operator, |>, aka function 
> > > concatenation.  At the time, the main thrust of the feedback was "cool, 
> > > like, but we need partial function application first so that the syntax 
> > > for callables isn't so crappy."
> > > 
> > > The PFA RFC is winding down now and is looking quite good, so it's time 
> > > to revisit pipes.
> > > 
> > > https://wiki.php.net/rfc/pipe-operator-v2
> > > 
> > > Nothing radical has changed in the proposal since last year.  I have 
> > > updated it against the latest master.  I also updated the RFC to use 
> > > more examples that assume PFA, as the result is legit much nicer.  i 
> > > also tested it locally with a combined partials-and-pipes branch to 
> > > make sure they play nicely together, and they do.  (Yay!)  Assuming PFA 
> > > passes I will include those tests in the pipes branch before this one 
> > > goes to a vote.
> > 
> > Hi again.
> > 
> > With PFA being declined, I've again reworked the Pipes RFC.
> > 
> > 1) It now does not use PFA in any examples, but it does use Nikita's 
> > first-class-callables RFC that looks like it's going to pass easily.
> > 
> > 2) With major hand-holding from Levi Morrison and Joe Watkins, the 
> > implementation has shifted a bit.  It now evaluates left-to-right, 
> > always, whereas the previous version evaluated right-to-left.  That is, 
> > instead of $a |> $b |> $c desugaring into $c($b($a)), it now becomes 
> > effectively $tmp = $a; $tmp = $b($tmp); $tmp = $c($tmp);  That matters 
> > if $b or $c are function calls that return a callable, as they are then 
> > only called when the pipeline gets to that part of the expression.  (If 
> > all the functions involved are pure functions, then it doesn't make a 
> > difference in practice.)
> > 
> > 3) I included references to several existing PHP libraries that 
> > implement similar logic, in mostly complex and ugly ways.
> > 
> > 4) Of note, Brent posted a Twitter poll last week about pipes, and the 
> > response was overwhelmingly in favor.  
> > (https://twitter.com/brendt_gd/status/1408271132650885123)  Naturally a 
> > Twitter poll is extremely unscientific, but I think between the 
> > existing libraries and the response there the answer to the question 
> > "is there actually a demand for this feature?" is unquestionably yes.
> > 
> > 5) Examples have been reworked to be a bit prettier.
> > 
> > 6) Added another language reference that has a pipe operator that works 
> > basically like described here. (OCaml)
> > 
> > I am planning to take this version of the RFC to a vote on Monday or 
> > Tuesday, as Tuesday is the last day possible to start a vote for 8.1 
> > features.
> > 
> > --Larry Garfield
> 
> Based on feedback on the PR, I've updated the RFC to forbid functions 
> that pass or return by reference.  They're not really useful in pipes 
> at all, and were only supported before because the implementation 
> happened to allow it.
> 
> The PR hasn't been updated for that yet, but I figure that's easy 
> enough to update post-vote if it passes.

Sorry for the noise, but after some discussion with Joe it looks like blocking 
references in pipes is actually much harder than it sounded like, and would 
require a completely opcode based implementation rather than the completely 
AST-based implementation.  References on pipes are not really useful but in 
practice they don't hurt anything.  I've instead added more tests to validate 
that they behave "as expected" and noted that in the RFC instead.

--Larry Garfield

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



Re: [PHP-DEV] [RFC] Pipe Operator, take 2

2021-07-05 Thread Larry Garfield
On Sat, Jul 3, 2021, at 9:12 PM, Larry Garfield wrote:
> On Mon, Jun 7, 2021, at 2:00 PM, Larry Garfield wrote:
> > Hi folks. Me again.
> > 
> > A year ago, I posted an RFC for a pipe operator, |>, aka function 
> > concatenation.  At the time, the main thrust of the feedback was "cool, 
> > like, but we need partial function application first so that the syntax 
> > for callables isn't so crappy."
> > 
> > The PFA RFC is winding down now and is looking quite good, so it's time 
> > to revisit pipes.
> > 
> > https://wiki.php.net/rfc/pipe-operator-v2
> > 
> > Nothing radical has changed in the proposal since last year.  I have 
> > updated it against the latest master.  I also updated the RFC to use 
> > more examples that assume PFA, as the result is legit much nicer.  i 
> > also tested it locally with a combined partials-and-pipes branch to 
> > make sure they play nicely together, and they do.  (Yay!)  Assuming PFA 
> > passes I will include those tests in the pipes branch before this one 
> > goes to a vote.
> 
> Hi again.
> 
> With PFA being declined, I've again reworked the Pipes RFC.
> 
> 1) It now does not use PFA in any examples, but it does use Nikita's 
> first-class-callables RFC that looks like it's going to pass easily.
> 
> 2) With major hand-holding from Levi Morrison and Joe Watkins, the 
> implementation has shifted a bit.  It now evaluates left-to-right, 
> always, whereas the previous version evaluated right-to-left.  That is, 
> instead of $a |> $b |> $c desugaring into $c($b($a)), it now becomes 
> effectively $tmp = $a; $tmp = $b($tmp); $tmp = $c($tmp);  That matters 
> if $b or $c are function calls that return a callable, as they are then 
> only called when the pipeline gets to that part of the expression.  (If 
> all the functions involved are pure functions, then it doesn't make a 
> difference in practice.)
> 
> 3) I included references to several existing PHP libraries that 
> implement similar logic, in mostly complex and ugly ways.
> 
> 4) Of note, Brent posted a Twitter poll last week about pipes, and the 
> response was overwhelmingly in favor.  
> (https://twitter.com/brendt_gd/status/1408271132650885123)  Naturally a 
> Twitter poll is extremely unscientific, but I think between the 
> existing libraries and the response there the answer to the question 
> "is there actually a demand for this feature?" is unquestionably yes.
> 
> 5) Examples have been reworked to be a bit prettier.
> 
> 6) Added another language reference that has a pipe operator that works 
> basically like described here. (OCaml)
> 
> I am planning to take this version of the RFC to a vote on Monday or 
> Tuesday, as Tuesday is the last day possible to start a vote for 8.1 
> features.
> 
> --Larry Garfield

Based on feedback on the PR, I've updated the RFC to forbid functions that pass 
or return by reference.  They're not really useful in pipes at all, and were 
only supported before because the implementation happened to allow it.

The PR hasn't been updated for that yet, but I figure that's easy enough to 
update post-vote if it passes.

--Larry Garfield

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



Re: [PHP-DEV] [RFC] Pipe Operator, take 2

2021-07-04 Thread Larry Garfield
On Sun, Jul 4, 2021, at 2:18 AM, Olle Härstedt wrote:
> 2021-07-04 4:12 GMT+02:00, Larry Garfield :
> > On Mon, Jun 7, 2021, at 2:00 PM, Larry Garfield wrote:
> >> Hi folks. Me again.
> >>
> >> A year ago, I posted an RFC for a pipe operator, |>, aka function
> >> concatenation.  At the time, the main thrust of the feedback was "cool,
> >> like, but we need partial function application first so that the syntax
> >> for callables isn't so crappy."
> >>
> >> The PFA RFC is winding down now and is looking quite good, so it's time
> >> to revisit pipes.
> >>
> >> https://wiki.php.net/rfc/pipe-operator-v2
> >>
> >> Nothing radical has changed in the proposal since last year.  I have
> >> updated it against the latest master.  I also updated the RFC to use
> >> more examples that assume PFA, as the result is legit much nicer.  i
> >> also tested it locally with a combined partials-and-pipes branch to
> >> make sure they play nicely together, and they do.  (Yay!)  Assuming PFA
> >> passes I will include those tests in the pipes branch before this one
> >> goes to a vote.
> >
> > Hi again.
> >
> > With PFA being declined, I've again reworked the Pipes RFC.
> >
> > 1) It now does not use PFA in any examples, but it does use Nikita's
> > first-class-callables RFC that looks like it's going to pass easily.
> >
> > 2) With major hand-holding from Levi Morrison and Joe Watkins, the
> > implementation has shifted a bit.  It now evaluates left-to-right, always,
> > whereas the previous version evaluated right-to-left.  That is, instead of
> > $a |> $b |> $c desugaring into $c($b($a)), it now becomes effectively $tmp =
> > $a; $tmp = $b($tmp); $tmp = $c($tmp);  That matters if $b or $c are function
> > calls that return a callable, as they are then only called when the pipeline
> > gets to that part of the expression.
> 
> Hi! Can you flesh out an example for this, please? Not sure I get the
> use-case where it matters. Couldn't find any example inside the PR
> either (the tests) that show-cased this particular implementation
> detail. Did I miss it?

The "evaluation order" test is for exactly that:

https://github.com/php/php-src/pull/7214/files#diff-526802c5ee7e0aa37afd67683d2c8b73c923b445737b3b44fae6bb5ea117ee97

With the old desugaring way, _test2() was called first before anything else.  
With the new way, it's called after _test1(), as most people would expect from 
reading it.

--Larry Garfield

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



Re: [PHP-DEV] [RFC] Pipe Operator, take 2

2021-07-04 Thread Olle Härstedt
2021-07-04 4:12 GMT+02:00, Larry Garfield :
> On Mon, Jun 7, 2021, at 2:00 PM, Larry Garfield wrote:
>> Hi folks. Me again.
>>
>> A year ago, I posted an RFC for a pipe operator, |>, aka function
>> concatenation.  At the time, the main thrust of the feedback was "cool,
>> like, but we need partial function application first so that the syntax
>> for callables isn't so crappy."
>>
>> The PFA RFC is winding down now and is looking quite good, so it's time
>> to revisit pipes.
>>
>> https://wiki.php.net/rfc/pipe-operator-v2
>>
>> Nothing radical has changed in the proposal since last year.  I have
>> updated it against the latest master.  I also updated the RFC to use
>> more examples that assume PFA, as the result is legit much nicer.  i
>> also tested it locally with a combined partials-and-pipes branch to
>> make sure they play nicely together, and they do.  (Yay!)  Assuming PFA
>> passes I will include those tests in the pipes branch before this one
>> goes to a vote.
>
> Hi again.
>
> With PFA being declined, I've again reworked the Pipes RFC.
>
> 1) It now does not use PFA in any examples, but it does use Nikita's
> first-class-callables RFC that looks like it's going to pass easily.
>
> 2) With major hand-holding from Levi Morrison and Joe Watkins, the
> implementation has shifted a bit.  It now evaluates left-to-right, always,
> whereas the previous version evaluated right-to-left.  That is, instead of
> $a |> $b |> $c desugaring into $c($b($a)), it now becomes effectively $tmp =
> $a; $tmp = $b($tmp); $tmp = $c($tmp);  That matters if $b or $c are function
> calls that return a callable, as they are then only called when the pipeline
> gets to that part of the expression.

Hi! Can you flesh out an example for this, please? Not sure I get the
use-case where it matters. Couldn't find any example inside the PR
either (the tests) that show-cased this particular implementation
detail. Did I miss it?

Olle

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



Re: [PHP-DEV] [RFC] Pipe Operator, take 2

2021-07-03 Thread Larry Garfield
On Mon, Jun 7, 2021, at 2:00 PM, Larry Garfield wrote:
> Hi folks. Me again.
> 
> A year ago, I posted an RFC for a pipe operator, |>, aka function 
> concatenation.  At the time, the main thrust of the feedback was "cool, 
> like, but we need partial function application first so that the syntax 
> for callables isn't so crappy."
> 
> The PFA RFC is winding down now and is looking quite good, so it's time 
> to revisit pipes.
> 
> https://wiki.php.net/rfc/pipe-operator-v2
> 
> Nothing radical has changed in the proposal since last year.  I have 
> updated it against the latest master.  I also updated the RFC to use 
> more examples that assume PFA, as the result is legit much nicer.  i 
> also tested it locally with a combined partials-and-pipes branch to 
> make sure they play nicely together, and they do.  (Yay!)  Assuming PFA 
> passes I will include those tests in the pipes branch before this one 
> goes to a vote.

Hi again.

With PFA being declined, I've again reworked the Pipes RFC.

1) It now does not use PFA in any examples, but it does use Nikita's 
first-class-callables RFC that looks like it's going to pass easily.

2) With major hand-holding from Levi Morrison and Joe Watkins, the 
implementation has shifted a bit.  It now evaluates left-to-right, always, 
whereas the previous version evaluated right-to-left.  That is, instead of $a 
|> $b |> $c desugaring into $c($b($a)), it now becomes effectively $tmp = $a; 
$tmp = $b($tmp); $tmp = $c($tmp);  That matters if $b or $c are function calls 
that return a callable, as they are then only called when the pipeline gets to 
that part of the expression.  (If all the functions involved are pure 
functions, then it doesn't make a difference in practice.)

3) I included references to several existing PHP libraries that implement 
similar logic, in mostly complex and ugly ways.

4) Of note, Brent posted a Twitter poll last week about pipes, and the response 
was overwhelmingly in favor.  
(https://twitter.com/brendt_gd/status/1408271132650885123)  Naturally a Twitter 
poll is extremely unscientific, but I think between the existing libraries and 
the response there the answer to the question "is there actually a demand for 
this feature?" is unquestionably yes.

5) Examples have been reworked to be a bit prettier.

6) Added another language reference that has a pipe operator that works 
basically like described here. (OCaml)

I am planning to take this version of the RFC to a vote on Monday or Tuesday, 
as Tuesday is the last day possible to start a vote for 8.1 features.

--Larry Garfield

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



Re: [PHP-DEV] [RFC] Pipe Operator, take 2

2021-06-29 Thread Olle Härstedt
2021-06-29 0:54 GMT+02:00, Larry Garfield :
> On Mon, Jun 28, 2021, at 5:30 PM, Olle Härstedt wrote:
>
>> Mm. Assoc arrays are by now known to be not so good. I hope...
>
> There are millions of PHP sites build on anonymous arrays today.
>
>> OCaml is strictly evaluated, not lazy like Haskell. So the order might
>> matter, dunno, I don't use this operator often. :) My point was mostly
>> that it's very easy to add in OCaml - just one line. And as in
>> Haskell, you can define operators in your modules. Similarly, in PHP
>> it's easy to do super-dynamic stuff like "new $someclass", which is
>> not remotely possible in FP (good or bad, depending on your religion).
>>
>> Adding a new pipe keyword is like the list() keyword, kind of. A bad
>> idea, haha. But I think all stones can be turned, if this RFC now gets
>> a no. :/
>>
>> 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? Could reduce the complexity while still covering maybe 80% of
>> the use-cases? Same with removing support for named arguments. So '?'
>> would only be a short-cut to get rid of boilerplate like `$strlen =
>> fn($x) => strlen($x)`.
>
> 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.  Once you've done that, supporting one
> placeholder or multiple, variadics or not, etc. is only a small incremental
> increase in complexity.
>
>> > Overall, I really don't like the idea of special-casing pipes to change
>> > what
>> > symbol table gets looked up.
>>
>> Still wondering if this could be a per-file or per-library setting
>> somehow, to opt-in into pipe behaviour when so desired. Or rather, to
>> opt-in into this or that behaviour needed to do more idiomatic pipe.
>>
>> Here's one boilerplaty pipe:
>
> *snip*
>
> We're in the pipe thread here, not PFA. :-)  And really, you're solving the
> wrong problem.  Pipes are trivial.  They're only clunky because of PHP's
> lack of decent callable syntax.  PFA gives us that, but the engine makes the
> implementation more complex than it seems like at first glance.
>
> Trying to come up with complex workarounds to make pipes pretty without
> helping anything else is a fool's errand, especially when we have a working
> PFA RFC that's about to end voting.  (And right now is losing by a very slim
> margin, but could pass if a few people change their minds.)
>
> Aside from something like Nikita's ...-only function reference RFC, which
> only handles half the problem (it doesn't do anything to make multi-arg
> functions work with pipes at all), any other solution is going to end up
> reinventing PFA one way or another, or reinventing existing ugly user-space
> libraries. one way or another
>
> I've not yet decided if I'm going to bring pipes to a vote if PFA doesn't
> pass.  I'm tempted to, but it would require rewriting all the RFC text back
> to the uglier version without PFA, and yeah, it's not going to look as
> pretty.  And the main pushback a year ago when I first brought it up was
> "PFA first, please, so the callable syntax isn't ugly."  And... here we
> are.
>
> --Larry Garfield

Is there no "pre-vote" process for RFCs? For example, letting the
voting members *rate* different alternatives, in a ranking fashion, to
see which one is most and least popular. Feels like a lot of work is
getting wasted if something is voted down on a small margin.

Olle

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



Re: [PHP-DEV] [RFC] Pipe Operator, take 2

2021-06-28 Thread Olle Härstedt
> 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.  Once you've done that, supporting one
> placeholder or multiple, variadics or not, etc. is only a small incremental
> increase in complexity.

Hm, I was thinking more about the conceptual complexity, not the
implementation, but seems like the argument "cover all expected
use-cases" was used too. :) So no half-measures...

Thanks for your feedback.

Olle

>> > Overall, I really don't like the idea of special-casing pipes to change
>> > what
>> > symbol table gets looked up.
>>
>> Still wondering if this could be a per-file or per-library setting
>> somehow, to opt-in into pipe behaviour when so desired. Or rather, to
>> opt-in into this or that behaviour needed to do more idiomatic pipe.
>>
>> Here's one boilerplaty pipe:
>
> *snip*
>
> We're in the pipe thread here, not PFA. :-)  And really, you're solving the
> wrong problem.  Pipes are trivial.  They're only clunky because of PHP's
> lack of decent callable syntax.  PFA gives us that, but the engine makes the
> implementation more complex than it seems like at first glance.
>
> Trying to come up with complex workarounds to make pipes pretty without
> helping anything else is a fool's errand, especially when we have a working
> PFA RFC that's about to end voting.  (And right now is losing by a very slim
> margin, but could pass if a few people change their minds.)
>
> Aside from something like Nikita's ...-only function reference RFC, which
> only handles half the problem (it doesn't do anything to make multi-arg
> functions work with pipes at all), any other solution is going to end up
> reinventing PFA one way or another, or reinventing existing ugly user-space
> libraries. one way or another
>
> I've not yet decided if I'm going to bring pipes to a vote if PFA doesn't
> pass.  I'm tempted to, but it would require rewriting all the RFC text back
> to the uglier version without PFA, and yeah, it's not going to look as
> pretty.  And the main pushback a year ago when I first brought it up was
> "PFA first, please, so the callable syntax isn't ugly."  And... here we
> are.
>
> --Larry Garfield

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



Re: [PHP-DEV] [RFC] Pipe Operator, take 2

2021-06-28 Thread Larry Garfield
On Mon, Jun 28, 2021, at 5:30 PM, Olle Härstedt wrote:

> Mm. Assoc arrays are by now known to be not so good. I hope...

There are millions of PHP sites build on anonymous arrays today.

> OCaml is strictly evaluated, not lazy like Haskell. So the order might
> matter, dunno, I don't use this operator often. :) My point was mostly
> that it's very easy to add in OCaml - just one line. And as in
> Haskell, you can define operators in your modules. Similarly, in PHP
> it's easy to do super-dynamic stuff like "new $someclass", which is
> not remotely possible in FP (good or bad, depending on your religion).
> 
> Adding a new pipe keyword is like the list() keyword, kind of. A bad
> idea, haha. But I think all stones can be turned, if this RFC now gets
> a no. :/
> 
> 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? Could reduce the complexity while still covering maybe 80% of
> the use-cases? Same with removing support for named arguments. So '?'
> would only be a short-cut to get rid of boilerplate like `$strlen =
> fn($x) => strlen($x)`.

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.  Once you've done that, supporting one 
placeholder or multiple, variadics or not, etc. is only a small incremental 
increase in complexity.

> > Overall, I really don't like the idea of special-casing pipes to change what
> > symbol table gets looked up.
> 
> Still wondering if this could be a per-file or per-library setting
> somehow, to opt-in into pipe behaviour when so desired. Or rather, to
> opt-in into this or that behaviour needed to do more idiomatic pipe.
> 
> Here's one boilerplaty pipe:

*snip*

We're in the pipe thread here, not PFA. :-)  And really, you're solving the 
wrong problem.  Pipes are trivial.  They're only clunky because of PHP's lack 
of decent callable syntax.  PFA gives us that, but the engine makes the 
implementation more complex than it seems like at first glance.

Trying to come up with complex workarounds to make pipes pretty without helping 
anything else is a fool's errand, especially when we have a working PFA RFC 
that's about to end voting.  (And right now is losing by a very slim margin, 
but could pass if a few people change their minds.)

Aside from something like Nikita's ...-only function reference RFC, which only 
handles half the problem (it doesn't do anything to make multi-arg functions 
work with pipes at all), any other solution is going to end up reinventing PFA 
one way or another, or reinventing existing ugly user-space libraries. one way 
or another

I've not yet decided if I'm going to bring pipes to a vote if PFA doesn't pass. 
 I'm tempted to, but it would require rewriting all the RFC text back to the 
uglier version without PFA, and yeah, it's not going to look as pretty.  And 
the main pushback a year ago when I first brought it up was "PFA first, please, 
so the callable syntax isn't ugly."  And... here we are.

--Larry Garfield

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



Re: [PHP-DEV] [RFC] Pipe Operator, take 2

2021-06-28 Thread Olle Härstedt
2021-06-29 0:06 GMT+02:00, Rowan Tommins :
> On 28/06/2021 21:28, Olle Härstedt wrote:
>> Sorry for hijacking the thread, but are there no other alternatives,
>> really? Just brainstorming:
>>
>> 1) Setting to silence the warning.
>
>
> Just to reiterate: in PHP 8.0, an undefined constant is not a warning,
> it's an error. My apologies to code golfers: you can no longer save two
> bytes by leaving the quote marks off your strings.
>
> However, that's not really the problem. The problem is when there *is* a
> constant with that name:
>
> const foo='strtoupper';
> function foo($x) { return 'test'; }
> $input = ['hello', 'world'];
> var_dump( array_map(foo, $input) ); // this runs strtoupper(), not foo()
>
> This doesn't work even in old versions of PHP where undefined constants
> fell back to strings.
>
> Even in cases where this trick did work in older versions of PHP, it was
> just a variant of option one, "use our current ugly callable syntax" -
> it saved you those two bytes, but it didn't actually provide you a
> function reference.
>
> Unifying the constant and function name tables would not be to just a
> different way of writing strings, it would let array_map(foo, $input)
> actually check that function foo existed, and represent callables as a
> proper type. Meanwhile, to let array_map($object->foo, $input) do the
> same thing (instead of the current [$object, 'foo'] syntax) you also
> need to unify the method and property tables, which is probably even
> harder.
>
>
>
>> 2) Setting to silence the warning IF and only if argument expects a
>> callable, like in array_map (won't work with a pipe() function,
>> though, since pipe() would take any number of arguments and that can't
>> be typed)
>
>
> In the general case, this is a non-starter: the parameters need to be
> parsed from the source code before function definitions are even known.
> You could special-case a handful of built-in functions, but that would
> be extremely clunky.
>
>
>
>> 3) Silence the warning if you type-case explicitly, like in
>> `pipe($start, (callable) htmlentities);`. Another alternative is
>> `(fn)` as a type-cast. Not much better than `pipe($start,
>> htmlentities(?))`, I guess. Just different style.
>
>
> This falls into my third option: "add a dedicated callable syntax". That
> could be something that looks a bit like PFA but isn't, like Nikita's
> RFC; or something that looks a bit like a type cast; or any number of
> other ideas which have been brainstormed for about as long as I've been
> programming PHP.
>
>
>> 4) Silence the warning ONLY when it's the right-hand argument to pipe
>> operator, like `$start |> str_len`.
>
>
> Re-wording this as "interpret the unquoted word as a function reference
> rather than a constant when...", this one is at least plausible. In
> practice, though, a lot of functions don't take only one parameter, so
> the previous pipe proposal included a placeholder for which argument you
> wanted to "pipe into". At which point you don't need to special case
> keywords, because you can just write this:
>
> $start |> str_len($$)

True. I wish we had numbers for how common the case is when you DON'T
want to pipe into the first argument. If it's rare enough, it might be
worth it to let the rare cases be dealt with by writing manual
lambdas. So allow some boilerplate. Another alternative would be to
add both '?' and parsing unquoted string as function reference
together with pipe operator, but start with the simple one (whichever
that is, I wouldn't know). Or start with the one that has chance of
being accepted by the voters. :)

> Regards,
>
> --
> Rowan Tommins
> [IMSoP]

Thanks for your explanations!

Olle

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



Re: [PHP-DEV] [RFC] Pipe Operator, take 2

2021-06-28 Thread Olle Härstedt
2021-06-28 23:36 GMT+02:00, Larry Garfield :
> On Mon, Jun 28, 2021, at 3:42 PM, Olle Härstedt wrote:
>> 2021-06-28 22:12 GMT+02:00, Larry Garfield :
>> > On Mon, Jun 28, 2021, at 3:04 PM, Rowan Tommins wrote:
>> >> On 28/06/2021 20:25, Olle Härstedt wrote:
>> >> > Usage (ignoring the pesky undefined constant warnings ><):
>> >>
>> >>
>> >> Unfortunately, you can't ignore those warnings; not least because
>> >> they're fatal errors in PHP 8, as they frankly should have been in PHP
>> >> 3.
>> >>
>> >> You can use our current ugly callable syntax (strings and two-element
>> >> arrays); you can tackle the complexity of unifying functions with
>> >> constants, and methods with properties (as Levi explained in the other
>> >> thread); or you can add a dedicated callable syntax, which the PFA
>> >> proposal gets us with bells on.
>> >>
>> >> Regards,
>> >
>> > I think that's a pretty good summary.  There's nothing that pipes or
>> > partials do that you couldn't emulate in user-space today (really, since
>> > 5.3
>> > is you really wanted to).  The emulation is just butt-ugly and slower,
>> > which
>> > is why most people don't do it except in very specific cases or if they
>> > have
>> > a user-space library available that makes it slightly less butt-ugly.
>> >
>> > The purpose of PFA and pipes (and short functions, and auto-capture
>> > closures, and basically everything else I've been talking about all
>> > year) is
>> > to make those things prettier and as fast as reasonable, which makes
>> > using
>> > those techniques more natural.  Once you start down that path, though,
>> > there's really no usable solution before you get down as far as... PFA
>> > and
>> > Pipes in their current form.
>> >
>> > --Larry Garfield
>>
>> The challenge is to write something that's pretty enough to be
>> considered idiomatic. :) The pipe operator in OCaml is defined by one
>> line:
>>
>> let (|>) v f = f v
>>
>> It wasn't always part of core, but eventually it was so common, it got
>> included by default. Same could happen with a pipe() function in PHP,
>> without the pipe operator, or that the function becomes so common, a
>> new keyword is added instead: `pipe`. But it could probably not happen
>> with a Pipe object requiring you to write ->pipe() at every step -
>> it's too much ceremony and boilerplate.
>>
>> By the way, that's alternative 5) New keyword `pipe` to make the
>> warning about constants shut up in a certain scope. Plus some other
>> magic to allow nice chaining. ^^
>>
>> Olle
>
> "Idiomatic PHP" consists primarily of associative arrays, used in ways no
> sane person would ever use a dictionary, but the code is in a method so it
> gets called OOP even though it's barely procedural.
>
> That's not an idiom I have any interest in supporting, and have in fact made
> a career out of training people out of. :-)
>
> There are *already* libraries that let you write ->pipe().  The PHP League
> has one, for instance:
>
> https://github.com/thephpleague/pipeline
>
> I've seen others, but they're no less ugly and offer no better migration
> path into a core syntax.  PHP is just not designed as a user-extensible
> language.  (cf, "Growing a Language" by Guy Steele, one of the best
> presentations ever given: https://www.youtube.com/watch?v=_ahvzDzKdB0)
>
> Also of note, the OCaml definition there is almost exactly the same as the
> current patch; there's a request out I'm working on now to change the
> implementation to ensure that the LHS is fully evaluated before the RHS, but
> it's interesting to see that OCaml's version does have the out-of-order
> challenge.  (Although in a functional language it's semantically a
> meaningless difference, by design.)
>
> Overall, I really don't like the idea of special-casing pipes to change what
> symbol table gets looked up.  That's just asking for edge cases to bite us
> later, especially when the root problem isn't with pipes in the first place;
> it's with PHP lacking either a function-reference syntax or PFA (which gives
> us a function-reference syntax for free).  Fix the real problem, don't hack
> around it in what should be a very simple feature.
>
> --Larry Garfield

Mm. Assoc arrays are by now known to be not so good. I hope...

OCaml is strictly evaluated, not lazy like Haskell. So the order might
matter, dunno, I don't use this operator often. :) My point was mostly
that it's very easy to add in OCaml - just one line. And as in
Haskell, you can define operators in your modules. Similarly, in PHP
it's easy to do super-dynamic stuff like "new $someclass", which is
not remotely possible in FP (good or bad, depending on your religion).

Adding a new pipe keyword is like the list() keyword, kind of. A bad
idea, haha. But I think all stones can be turned, if this RFC now gets
a no. :/

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? Could reduce the complexity while still 

Re: [PHP-DEV] [RFC] Pipe Operator, take 2

2021-06-28 Thread Rowan Tommins

On 28/06/2021 21:28, Olle Härstedt wrote:

Sorry for hijacking the thread, but are there no other alternatives,
really? Just brainstorming:

1) Setting to silence the warning.



Just to reiterate: in PHP 8.0, an undefined constant is not a warning, 
it's an error. My apologies to code golfers: you can no longer save two 
bytes by leaving the quote marks off your strings.


However, that's not really the problem. The problem is when there *is* a 
constant with that name:


const foo='strtoupper';
function foo($x) { return 'test'; }
$input = ['hello', 'world'];
var_dump( array_map(foo, $input) ); // this runs strtoupper(), not foo()

This doesn't work even in old versions of PHP where undefined constants 
fell back to strings.


Even in cases where this trick did work in older versions of PHP, it was 
just a variant of option one, "use our current ugly callable syntax" - 
it saved you those two bytes, but it didn't actually provide you a 
function reference.


Unifying the constant and function name tables would not be to just a 
different way of writing strings, it would let array_map(foo, $input) 
actually check that function foo existed, and represent callables as a 
proper type. Meanwhile, to let array_map($object->foo, $input) do the 
same thing (instead of the current [$object, 'foo'] syntax) you also 
need to unify the method and property tables, which is probably even harder.





2) Setting to silence the warning IF and only if argument expects a
callable, like in array_map (won't work with a pipe() function,
though, since pipe() would take any number of arguments and that can't
be typed)



In the general case, this is a non-starter: the parameters need to be 
parsed from the source code before function definitions are even known. 
You could special-case a handful of built-in functions, but that would 
be extremely clunky.





3) Silence the warning if you type-case explicitly, like in
`pipe($start, (callable) htmlentities);`. Another alternative is
`(fn)` as a type-cast. Not much better than `pipe($start,
htmlentities(?))`, I guess. Just different style.



This falls into my third option: "add a dedicated callable syntax". That 
could be something that looks a bit like PFA but isn't, like Nikita's 
RFC; or something that looks a bit like a type cast; or any number of 
other ideas which have been brainstormed for about as long as I've been 
programming PHP.




4) Silence the warning ONLY when it's the right-hand argument to pipe
operator, like `$start |> str_len`.



Re-wording this as "interpret the unquoted word as a function reference 
rather than a constant when...", this one is at least plausible. In 
practice, though, a lot of functions don't take only one parameter, so 
the previous pipe proposal included a placeholder for which argument you 
wanted to "pipe into". At which point you don't need to special case 
keywords, because you can just write this:


$start |> str_len($$)


Regards,

--
Rowan Tommins
[IMSoP]

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



Re: [PHP-DEV] [RFC] Pipe Operator, take 2

2021-06-28 Thread Larry Garfield
On Mon, Jun 28, 2021, at 3:42 PM, Olle Härstedt wrote:
> 2021-06-28 22:12 GMT+02:00, Larry Garfield :
> > On Mon, Jun 28, 2021, at 3:04 PM, Rowan Tommins wrote:
> >> On 28/06/2021 20:25, Olle Härstedt wrote:
> >> > Usage (ignoring the pesky undefined constant warnings ><):
> >>
> >>
> >> Unfortunately, you can't ignore those warnings; not least because
> >> they're fatal errors in PHP 8, as they frankly should have been in PHP 3.
> >>
> >> You can use our current ugly callable syntax (strings and two-element
> >> arrays); you can tackle the complexity of unifying functions with
> >> constants, and methods with properties (as Levi explained in the other
> >> thread); or you can add a dedicated callable syntax, which the PFA
> >> proposal gets us with bells on.
> >>
> >> Regards,
> >
> > I think that's a pretty good summary.  There's nothing that pipes or
> > partials do that you couldn't emulate in user-space today (really, since 5.3
> > is you really wanted to).  The emulation is just butt-ugly and slower, which
> > is why most people don't do it except in very specific cases or if they have
> > a user-space library available that makes it slightly less butt-ugly.
> >
> > The purpose of PFA and pipes (and short functions, and auto-capture
> > closures, and basically everything else I've been talking about all year) is
> > to make those things prettier and as fast as reasonable, which makes using
> > those techniques more natural.  Once you start down that path, though,
> > there's really no usable solution before you get down as far as... PFA and
> > Pipes in their current form.
> >
> > --Larry Garfield
> 
> The challenge is to write something that's pretty enough to be
> considered idiomatic. :) The pipe operator in OCaml is defined by one
> line:
> 
> let (|>) v f = f v
> 
> It wasn't always part of core, but eventually it was so common, it got
> included by default. Same could happen with a pipe() function in PHP,
> without the pipe operator, or that the function becomes so common, a
> new keyword is added instead: `pipe`. But it could probably not happen
> with a Pipe object requiring you to write ->pipe() at every step -
> it's too much ceremony and boilerplate.
> 
> By the way, that's alternative 5) New keyword `pipe` to make the
> warning about constants shut up in a certain scope. Plus some other
> magic to allow nice chaining. ^^
> 
> Olle

"Idiomatic PHP" consists primarily of associative arrays, used in ways no sane 
person would ever use a dictionary, but the code is in a method so it gets 
called OOP even though it's barely procedural.

That's not an idiom I have any interest in supporting, and have in fact made a 
career out of training people out of. :-)

There are *already* libraries that let you write ->pipe().  The PHP League has 
one, for instance: 

https://github.com/thephpleague/pipeline

I've seen others, but they're no less ugly and offer no better migration path 
into a core syntax.  PHP is just not designed as a user-extensible language.  
(cf, "Growing a Language" by Guy Steele, one of the best presentations ever 
given: https://www.youtube.com/watch?v=_ahvzDzKdB0)

Also of note, the OCaml definition there is almost exactly the same as the 
current patch; there's a request out I'm working on now to change the 
implementation to ensure that the LHS is fully evaluated before the RHS, but 
it's interesting to see that OCaml's version does have the out-of-order 
challenge.  (Although in a functional language it's semantically a meaningless 
difference, by design.)

Overall, I really don't like the idea of special-casing pipes to change what 
symbol table gets looked up.  That's just asking for edge cases to bite us 
later, especially when the root problem isn't with pipes in the first place; 
it's with PHP lacking either a function-reference syntax or PFA (which gives us 
a function-reference syntax for free).  Fix the real problem, don't hack around 
it in what should be a very simple feature.

--Larry Garfield

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



Re: [PHP-DEV] [RFC] Pipe Operator, take 2

2021-06-28 Thread Olle Härstedt
2021-06-28 22:12 GMT+02:00, Larry Garfield :
> On Mon, Jun 28, 2021, at 3:04 PM, Rowan Tommins wrote:
>> On 28/06/2021 20:25, Olle Härstedt wrote:
>> > Usage (ignoring the pesky undefined constant warnings ><):
>>
>>
>> Unfortunately, you can't ignore those warnings; not least because
>> they're fatal errors in PHP 8, as they frankly should have been in PHP 3.
>>
>> You can use our current ugly callable syntax (strings and two-element
>> arrays); you can tackle the complexity of unifying functions with
>> constants, and methods with properties (as Levi explained in the other
>> thread); or you can add a dedicated callable syntax, which the PFA
>> proposal gets us with bells on.
>>
>> Regards,
>
> I think that's a pretty good summary.  There's nothing that pipes or
> partials do that you couldn't emulate in user-space today (really, since 5.3
> is you really wanted to).  The emulation is just butt-ugly and slower, which
> is why most people don't do it except in very specific cases or if they have
> a user-space library available that makes it slightly less butt-ugly.
>
> The purpose of PFA and pipes (and short functions, and auto-capture
> closures, and basically everything else I've been talking about all year) is
> to make those things prettier and as fast as reasonable, which makes using
> those techniques more natural.  Once you start down that path, though,
> there's really no usable solution before you get down as far as... PFA and
> Pipes in their current form.
>
> --Larry Garfield

The challenge is to write something that's pretty enough to be
considered idiomatic. :) The pipe operator in OCaml is defined by one
line:

let (|>) v f = f v

It wasn't always part of core, but eventually it was so common, it got
included by default. Same could happen with a pipe() function in PHP,
without the pipe operator, or that the function becomes so common, a
new keyword is added instead: `pipe`. But it could probably not happen
with a Pipe object requiring you to write ->pipe() at every step -
it's too much ceremony and boilerplate.

By the way, that's alternative 5) New keyword `pipe` to make the
warning about constants shut up in a certain scope. Plus some other
magic to allow nice chaining. ^^

Olle

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



Re: [PHP-DEV] [RFC] Pipe Operator, take 2

2021-06-28 Thread Olle Härstedt
2021-06-28 22:04 GMT+02:00, Rowan Tommins :
> On 28/06/2021 20:25, Olle Härstedt wrote:
>> Usage (ignoring the pesky undefined constant warnings ><):
>
>
> Unfortunately, you can't ignore those warnings; not least because
> they're fatal errors in PHP 8, as they frankly should have been in PHP 3.
>
> You can use our current ugly callable syntax (strings and two-element
> arrays); you can tackle the complexity of unifying functions with
> constants, and methods with properties (as Levi explained in the other
> thread); or you can add a dedicated callable syntax, which the PFA
> proposal gets us with bells on.

Sorry for hijacking the thread, but are there no other alternatives,
really? Just brainstorming:

1) Setting to silence the warning. Probably frowned upon, AND requires
that functions/methods are case sensitive, which they are not right
now. BUT, constants are always case sensitive since 7.3, so the risk
of collision is not that high...? Assuming constants are by convention
always UPPER_CASE, and functions either snake_case or camelCase. You
can argue that the setting together with a CI to check cases would be
reasonably safe.

2) Setting to silence the warning IF and only if argument expects a
callable, like in array_map (won't work with a pipe() function,
though, since pipe() would take any number of arguments and that can't
be typed)

3) Silence the warning if you type-case explicitly, like in
`pipe($start, (callable) htmlentities);`. Another alternative is
`(fn)` as a type-cast. Not much better than `pipe($start,
htmlentities(?))`, I guess. Just different style.

4) Silence the warning ONLY when it's the right-hand argument to pipe
operator, like `$start |> str_len`.

All stupid?

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



Re: [PHP-DEV] [RFC] Pipe Operator, take 2

2021-06-28 Thread Larry Garfield
On Mon, Jun 28, 2021, at 3:04 PM, Rowan Tommins wrote:
> On 28/06/2021 20:25, Olle Härstedt wrote:
> > Usage (ignoring the pesky undefined constant warnings ><):
> 
> 
> Unfortunately, you can't ignore those warnings; not least because 
> they're fatal errors in PHP 8, as they frankly should have been in PHP 3.
> 
> You can use our current ugly callable syntax (strings and two-element 
> arrays); you can tackle the complexity of unifying functions with 
> constants, and methods with properties (as Levi explained in the other 
> thread); or you can add a dedicated callable syntax, which the PFA 
> proposal gets us with bells on.
> 
> Regards,

I think that's a pretty good summary.  There's nothing that pipes or partials 
do that you couldn't emulate in user-space today (really, since 5.3 is you 
really wanted to).  The emulation is just butt-ugly and slower, which is why 
most people don't do it except in very specific cases or if they have a 
user-space library available that makes it slightly less butt-ugly.

The purpose of PFA and pipes (and short functions, and auto-capture closures, 
and basically everything else I've been talking about all year) is to make 
those things prettier and as fast as reasonable, which makes using those 
techniques more natural.  Once you start down that path, though, there's really 
no usable solution before you get down as far as... PFA and Pipes in their 
current form.

--Larry Garfield

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



Re: [PHP-DEV] [RFC] Pipe Operator, take 2

2021-06-28 Thread Rowan Tommins

On 28/06/2021 20:25, Olle Härstedt wrote:

Usage (ignoring the pesky undefined constant warnings ><):



Unfortunately, you can't ignore those warnings; not least because 
they're fatal errors in PHP 8, as they frankly should have been in PHP 3.


You can use our current ugly callable syntax (strings and two-element 
arrays); you can tackle the complexity of unifying functions with 
constants, and methods with properties (as Levi explained in the other 
thread); or you can add a dedicated callable syntax, which the PFA 
proposal gets us with bells on.


Regards,

--
Rowan Tommins
[IMSoP]

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



Re: [PHP-DEV] [RFC] Pipe Operator, take 2

2021-06-28 Thread Olle Härstedt
2021-06-07 21:00 GMT+02:00, Larry Garfield :
> Hi folks. Me again.
>
> A year ago, I posted an RFC for a pipe operator, |>, aka function
> concatenation.  At the time, the main thrust of the feedback was "cool,
> like, but we need partial function application first so that the syntax for
> callables isn't so crappy."
>
> The PFA RFC is winding down now and is looking quite good, so it's time to
> revisit pipes.
>
> https://wiki.php.net/rfc/pipe-operator-v2
>
> Nothing radical has changed in the proposal since last year.  I have updated
> it against the latest master.  I also updated the RFC to use more examples
> that assume PFA, as the result is legit much nicer.  i also tested it
> locally with a combined partials-and-pipes branch to make sure they play
> nicely together, and they do.  (Yay!)  Assuming PFA passes I will include
> those tests in the pipes branch before this one goes to a vote.
>
> --
>   Larry Garfield
>   la...@garfieldtech.com
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php

Hi ho,

Has it been discussed the difference between the pipe operator and a
simple pipe function? Something like

function pipe() {
$args = func_get_args();
$result = $args[0];
$functions = array_slice($args, 1);
foreach ($functions as $function) {
$result = $function($result);
}
return $result;
}

Usage (ignoring the pesky undefined constant warnings ><):

$result = pipe(
"Hello world",
htmlentities,
str_split,
fn ($x) => array_map(strtoupper, $x),
fn ($x) => array_filter($x, fn ($v) => $v !== 'O')
);

There's also pipe operator with object, but that's obviously too
verbose compared to the operator
(https://github.com/sebastiaanluca/php-pipe-operator).

Olle

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



Re: [PHP-DEV] [RFC] Pipe Operator, take 2

2021-06-08 Thread Guilliam Xavier
On Tue, Jun 8, 2021 at 4:09 PM Larry Garfield 
wrote:

> On Tue, Jun 8, 2021, at 5:41 AM, Guilliam Xavier wrote:
>
> > you forgot to update one
> > `explode(?)` to `str_split(?)`, and also, the first `fn($v) =>
> > 'strtoupper'` should be just `'strtoupper'`.
>
> I deliberately made that example extra verbose to show how ugly it can
> get, but I can shorten it.
>

Extra verbose would have been `fn($v) => strtoupper($v)`, there was
obviously a typo (already correct in the second equivalent code fragment).
Anyway, I see you fixed it, and also updated the Haskell section :thumbsup:


>
> > Also, quoting from
> >
> https://wiki.php.net/rfc/first_class_callable_syntax#partial_function_application
> > :
> >
> > """
> > Both approaches to the pipe operator have their advantages. The $$ based
> > variant allows using more than plain function calls in each pipeline step
> > (e.g. you could have $$->getName() as a step, something not possible with
> > PFA), and is also trivially free. A PFA-based optimization would entail
> > significant overhead relative to simple function calls, unless special
> > optimization for the pipe operator usage is introduced (which may not be
> > possible, depending on precise semantics).
> > """
> >
> > Could you (or Nikita) expand a bit on this (esp. the advantages of the
> PFA
> > approach / disadvantages of Hack's approach)?
>
> It's true PFA doesn't cover every possible RHS of pipes.  In practice, I
> think using the piped value as an object on which to invoke a method is the
> only major gap.  Normally in functional code you would use a lens in that
> case, which (if I am understanding those correctly; that's roughly at the
> edge of my functional understanding) is essentially a function call that
> wraps accessing a property or calling a method so that it feels more
> functional, and thus pipes cleanly.
>
> However, piping with callables has a number of advantages.
>
> 1) The implementation is vastly simpler.  It's simple enough that even I
> can manage it, whereas Hack-style would be more considerably implementation
> work.
>
> 2) I would argue it's more flexible.  Once you start thinking of
> callables/functions in a first class way, producing functions on the fly
> that do what you want becomes natural, and fits better with a
> pipe-to-callable model.  For instance, the comprehension-esque example
> (which I suspect will be one of the most common use cases of pipes) is far
> cleaner with a callable, as it can obviate any question about parameter
> order.
>
> Another example I threw together last night is this proof of concept last
> night, which works when pipes, enums, and partials are combined.  I don't
> think Hack-style would be capable of this, at least not as elegantly.
>
> https://gist.github.com/Crell/e484bb27372e7bc93516331a15069f97
>
> (That's essentially a "naked either monad".)
>
> 3) I disagree that the overhead of arbitrary callables is "significant."
> It's there, but at that point you're talking about optimizing function call
> counts, mostly on partials; unless you're using pipes for absolutely
> everything, go remove an SQL query or two and you'll get a bigger
> performance boost.
>
> 4) Far more languages have callable pipes.  Hack is, as far as I am aware,
> entirely alone in having pipes be combined with a custom expression syntax
> rather than just using functions/callables.  That isn't conclusive proof of
> anything, but it's certainly suggestive.
>
> I'm going to be moving forward with this approach one way or another (if
> for point 1 if nothing else).  I do believe it is the more flexible, more
> robust approach, and fits with the general strategy I recommend of small,
> targeted changes that combine with other small, targeted changes to offer
> more functionality than either of them alone.  That's exactly what we're
> doing here.
>

All good points IMHO.

Thanks!

-- 
Guilliam Xavier


Re: [PHP-DEV] [RFC] Pipe Operator, take 2

2021-06-08 Thread Larry Garfield
On Tue, Jun 8, 2021, at 5:41 AM, Guilliam Xavier wrote:

> > Hm.  You're right.  It used to, but it's been a very long time since
> > explode() allowed an empty split, apparently.  I updated the example to use
> > str_split, which is what I'd intended to do in this case.  Thanks.
> >
> 
> Are you thinking to implode()?  Anyway, you forgot to update one
> `explode(?)` to `str_split(?)`, and also, the first `fn($v) =>
> 'strtoupper'` should be just `'strtoupper'`.

I deliberately made that example extra verbose to show how ugly it can get, but 
I can shorten it.

> About Haskell, rather than (or in addition to) the function composition
> [not "concatenation"] (.), I would mention the reverse application operator
> (&):
> https://hackage.haskell.org/package/base-4.15.0.0/docs/Data-Function.html#v:-38-
> 
> One thing I note is that even with PFA, some examples still need an arrow
> function, e.g. the PSR-7 one:
> 
> ```
> ServerRequest::fromGlobals()
> |> authenticate(?)
> |> $router->resolveAction(?)
> |> fn($request) => $request->getAttribute('action')($request)
> /* ... */;
> ```
> 
> while in Hack you would write it as:
> 
> ```
> ServerRequest::fromGlobals()
> |> authenticate($$)
> |> $router->resolveAction($$)
> |> $$->getAttribute('action')($$)
> /* ... */;
> ```
> 
> Also, quoting from
> https://wiki.php.net/rfc/first_class_callable_syntax#partial_function_application
> :
> 
> """
> Both approaches to the pipe operator have their advantages. The $$ based
> variant allows using more than plain function calls in each pipeline step
> (e.g. you could have $$->getName() as a step, something not possible with
> PFA), and is also trivially free. A PFA-based optimization would entail
> significant overhead relative to simple function calls, unless special
> optimization for the pipe operator usage is introduced (which may not be
> possible, depending on precise semantics).
> """
> 
> Could you (or Nikita) expand a bit on this (esp. the advantages of the PFA
> approach / disadvantages of Hack's approach)?
> 
> Regards,

It's true PFA doesn't cover every possible RHS of pipes.  In practice, I think 
using the piped value as an object on which to invoke a method is the only 
major gap.  Normally in functional code you would use a lens in that case, 
which (if I am understanding those correctly; that's roughly at the edge of my 
functional understanding) is essentially a function call that wraps accessing a 
property or calling a method so that it feels more functional, and thus pipes 
cleanly.

However, piping with callables has a number of advantages.

1) The implementation is vastly simpler.  It's simple enough that even I can 
manage it, whereas Hack-style would be more considerably implementation work.  

2) I would argue it's more flexible.  Once you start thinking of 
callables/functions in a first class way, producing functions on the fly that 
do what you want becomes natural, and fits better with a pipe-to-callable 
model.  For instance, the comprehension-esque example (which I suspect will be 
one of the most common use cases of pipes) is far cleaner with a callable, as 
it can obviate any question about parameter order.  

Another example I threw together last night is this proof of concept last 
night, which works when pipes, enums, and partials are combined.  I don't think 
Hack-style would be capable of this, at least not as elegantly.

https://gist.github.com/Crell/e484bb27372e7bc93516331a15069f97

(That's essentially a "naked either monad".)

3) I disagree that the overhead of arbitrary callables is "significant."  It's 
there, but at that point you're talking about optimizing function call counts, 
mostly on partials; unless you're using pipes for absolutely everything, go 
remove an SQL query or two and you'll get a bigger performance boost.

4) Far more languages have callable pipes.  Hack is, as far as I am aware, 
entirely alone in having pipes be combined with a custom expression syntax 
rather than just using functions/callables.  That isn't conclusive proof of 
anything, but it's certainly suggestive.

I'm going to be moving forward with this approach one way or another (if for 
point 1 if nothing else).  I do believe it is the more flexible, more robust 
approach, and fits with the general strategy I recommend of small, targeted 
changes that combine with other small, targeted changes to offer more 
functionality than either of them alone.  That's exactly what we're doing here.

--Larry Garfield

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



Re: [PHP-DEV] [RFC] Pipe Operator, take 2

2021-06-08 Thread Guilliam Xavier
Hi,

On Tue, Jun 8, 2021 at 12:09 AM Larry Garfield 
wrote:

> On Mon, Jun 7, 2021, at 4:00 PM, Eugene Leonovich wrote:
> > On Mon, Jun 7, 2021 at 9:03 PM Larry Garfield 
> > wrote:
> >
> > > https://wiki.php.net/rfc/pipe-operator-v2
> > >
> > FTR, there are several typos in the "Hello World" examples
> (*strto*t*upper,
> > htmlent*i*ties*). Also, these examples will not work as written because
> > explode() expects two arguments and will fail if you pass only one:
> > https://3v4l.org/tLO0s.
>
> Hm.  You're right.  It used to, but it's been a very long time since
> explode() allowed an empty split, apparently.  I updated the example to use
> str_split, which is what I'd intended to do in this case.  Thanks.
>

Are you thinking to implode()?  Anyway, you forgot to update one
`explode(?)` to `str_split(?)`, and also, the first `fn($v) =>
'strtoupper'` should be just `'strtoupper'`.

About Haskell, rather than (or in addition to) the function composition
[not "concatenation"] (.), I would mention the reverse application operator
(&):
https://hackage.haskell.org/package/base-4.15.0.0/docs/Data-Function.html#v:-38-

One thing I note is that even with PFA, some examples still need an arrow
function, e.g. the PSR-7 one:

```
ServerRequest::fromGlobals()
|> authenticate(?)
|> $router->resolveAction(?)
|> fn($request) => $request->getAttribute('action')($request)
/* ... */;
```

while in Hack you would write it as:

```
ServerRequest::fromGlobals()
|> authenticate($$)
|> $router->resolveAction($$)
|> $$->getAttribute('action')($$)
/* ... */;
```

Also, quoting from
https://wiki.php.net/rfc/first_class_callable_syntax#partial_function_application
:

"""
Both approaches to the pipe operator have their advantages. The $$ based
variant allows using more than plain function calls in each pipeline step
(e.g. you could have $$->getName() as a step, something not possible with
PFA), and is also trivially free. A PFA-based optimization would entail
significant overhead relative to simple function calls, unless special
optimization for the pipe operator usage is introduced (which may not be
possible, depending on precise semantics).
"""

Could you (or Nikita) expand a bit on this (esp. the advantages of the PFA
approach / disadvantages of Hack's approach)?

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] [RFC] Pipe Operator, take 2

2021-06-07 Thread Mike Schinkel
> On Jun 7, 2021, at 9:39 PM, Larry Garfield  wrote:
> 
> On Mon, Jun 7, 2021, at 8:09 PM, Mike Schinkel wrote:
>> 
>>> On Jun 7, 2021, at 3:00 PM, Larry Garfield  wrote:
>>> 
>>> Hi folks. Me again.
>>> 
>>> A year ago, I posted an RFC for a pipe operator, |>, aka function 
>>> concatenation.  At the time, the main thrust of the feedback was "cool, 
>>> like, but we need partial function application first so that the syntax for 
>>> callables isn't so crappy."
>>> 
>>> The PFA RFC is winding down now and is looking quite good, so it's time to 
>>> revisit pipes.
>>> 
>>> https://wiki.php.net/rfc/pipe-operator-v2
>>> 
>>> Nothing radical has changed in the proposal since last year.  I have 
>>> updated it against the latest master.  I also updated the RFC to use more 
>>> examples that assume PFA, as the result is legit much nicer.  i also tested 
>>> it locally with a combined partials-and-pipes branch to make sure they play 
>>> nicely together, and they do.  (Yay!)  Assuming PFA passes I will include 
>>> those tests in the pipes branch before this one goes to a vote.
>> 
>> In general, much nicer with PFA than before.
>> 
>> A few questions though, although #1 is probably best answered by Derick 
>> Rethans:
>> 
>> 1. Will PHP consider a piped sequence a single expression?  More 
>> specifically, will XDEBUG consider it a single expression, or could 
>> XDEBUG be able to set a breakpoint at each pipe assuming they are on 
>> separate lines?  
>> 
>> I ask because if pipes were an indivisible expression from the 
>> standpoint of XDEBUG and breakpoints I would not want to see them 
>> included in PHP. Alternately if included in PHP I would avoid using 
>> them like the plague just like I avoid using fluent interfaces because 
>> of their inability to be breakpointed at each step in XDEBUG.
> 
> $foo |> bar(?) |> baz(?);
> 
> will produce the same AST as
> 
> baz(bar($foo));
> 
> So whatever Xdebug can do with that AST, it should still be able to do.

That is unfortunate.   

Few people write code or would write code like bazoom(baz(bar(foo($x 
because the trailing parenthesis make it far from ergonomic. What you are 
proposing therefore is an ergonomic way to convert a program into a single 
large expression (when taken to the limit.)

Given that your pipe RFC makes practical a style of coding that was previously 
not practical it begs the question of addressing intermediate steps in the AST 
to support breakpoints, which also might require XDEBUG to introspect the 
values on the calling stack.  

Unfortunately I do not know enough about how the internal representations work 
to argue that this be considered a must; hopefully Derick Rethans will comment 
on this.

-Mike

Re: [PHP-DEV] [RFC] Pipe Operator, take 2

2021-06-07 Thread Larry Garfield
On Mon, Jun 7, 2021, at 8:09 PM, Mike Schinkel wrote:
> 
> > On Jun 7, 2021, at 3:00 PM, Larry Garfield  wrote:
> > 
> > Hi folks. Me again.
> > 
> > A year ago, I posted an RFC for a pipe operator, |>, aka function 
> > concatenation.  At the time, the main thrust of the feedback was "cool, 
> > like, but we need partial function application first so that the syntax for 
> > callables isn't so crappy."
> > 
> > The PFA RFC is winding down now and is looking quite good, so it's time to 
> > revisit pipes.
> > 
> > https://wiki.php.net/rfc/pipe-operator-v2
> > 
> > Nothing radical has changed in the proposal since last year.  I have 
> > updated it against the latest master.  I also updated the RFC to use more 
> > examples that assume PFA, as the result is legit much nicer.  i also tested 
> > it locally with a combined partials-and-pipes branch to make sure they play 
> > nicely together, and they do.  (Yay!)  Assuming PFA passes I will include 
> > those tests in the pipes branch before this one goes to a vote.
> 
> In general, much nicer with PFA than before.
> 
> A few questions though, although #1 is probably best answered by Derick 
> Rethans:
> 
> 1. Will PHP consider a piped sequence a single expression?  More 
> specifically, will XDEBUG consider it a single expression, or could 
> XDEBUG be able to set a breakpoint at each pipe assuming they are on 
> separate lines?  
> 
> I ask because if pipes were an indivisible expression from the 
> standpoint of XDEBUG and breakpoints I would not want to see them 
> included in PHP. Alternately if included in PHP I would avoid using 
> them like the plague just like I avoid using fluent interfaces because 
> of their inability to be breakpointed at each step in XDEBUG.

$foo |> bar(?) |> baz(?);

will produce the same AST as

baz(bar($foo));

So whatever Xdebug can do with that AST, it should still be able to do.

> 2. Besides `throw` will there be a way to short-circuit evaluation 
> mid-way through the pipes without having to write all of the callables 
> to respect said short-circuiting and just return? 
> 
> For example, could returning an instance of an object that implements a 
> `ShortCircuitPipeInterface` allow the pipe to short-circuit, or some 
> other way to short-circuit and then determine after the pipe if it was 
> short-circuited?

What you're describing is effectively monads.  (There's that scary word again.) 
 That is not covered here, although I mention it in the future scope section.  
There's a couple of ways it could be implemented, although you can already do 
so today in user-space with a method instead of a dedicated operator.  The 
caveat is monads essentially have to be either untyped or use generics, so for 
now we're stuck with untyped monads.

Alternatively, you can wrap each callable in another function that wraps the 
short-circuiting behavior around it.  That's essentially "railroad oriented 
programming", a term coined by Scott Wlaschin:

https://fsharpforfunandprofit.com/rop/

In other words, "I want that, but it comes later, via something more robust."

--Larry Garfield

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



Re: [PHP-DEV] [RFC] Pipe Operator, take 2

2021-06-07 Thread Mike Schinkel



> On Jun 7, 2021, at 3:00 PM, Larry Garfield  wrote:
> 
> Hi folks. Me again.
> 
> A year ago, I posted an RFC for a pipe operator, |>, aka function 
> concatenation.  At the time, the main thrust of the feedback was "cool, like, 
> but we need partial function application first so that the syntax for 
> callables isn't so crappy."
> 
> The PFA RFC is winding down now and is looking quite good, so it's time to 
> revisit pipes.
> 
> https://wiki.php.net/rfc/pipe-operator-v2
> 
> Nothing radical has changed in the proposal since last year.  I have updated 
> it against the latest master.  I also updated the RFC to use more examples 
> that assume PFA, as the result is legit much nicer.  i also tested it locally 
> with a combined partials-and-pipes branch to make sure they play nicely 
> together, and they do.  (Yay!)  Assuming PFA passes I will include those 
> tests in the pipes branch before this one goes to a vote.

In general, much nicer with PFA than before.

A few questions though, although #1 is probably best answered by Derick Rethans:

1. Will PHP consider a piped sequence a single expression?  More specifically, 
will XDEBUG consider it a single expression, or could XDEBUG be able to set a 
breakpoint at each pipe assuming they are on separate lines?  

I ask because if pipes were an indivisible expression from the standpoint of 
XDEBUG and breakpoints I would not want to see them included in PHP. 
Alternately if included in PHP I would avoid using them like the plague just 
like I avoid using fluent interfaces because of their inability to be 
breakpointed at each step in XDEBUG.


2. Besides `throw` will there be a way to short-circuit evaluation mid-way 
through the pipes without having to write all of the callables to respect said 
short-circuiting and just return? 

For example, could returning an instance of an object that implements a 
`ShortCircuitPipeInterface` allow the pipe to short-circuit, or some other way 
to short-circuit and then determine after the pipe if it was short-circuited?

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



Re: [PHP-DEV] [RFC] Pipe Operator, take 2

2021-06-07 Thread Larry Garfield
On Mon, Jun 7, 2021, at 4:00 PM, Eugene Leonovich wrote:
> On Mon, Jun 7, 2021 at 9:03 PM Larry Garfield 
> wrote:
> 
> > Hi folks. Me again.
> >
> > A year ago, I posted an RFC for a pipe operator, |>, aka function
> > concatenation.  At the time, the main thrust of the feedback was "cool,
> > like, but we need partial function application first so that the syntax for
> > callables isn't so crappy."
> >
> > The PFA RFC is winding down now and is looking quite good, so it's time to
> > revisit pipes.
> >
> > https://wiki.php.net/rfc/pipe-operator-v2
> >
> > Nothing radical has changed in the proposal since last year.  I have
> > updated it against the latest master.  I also updated the RFC to use more
> > examples that assume PFA, as the result is legit much nicer.  i also tested
> > it locally with a combined partials-and-pipes branch to make sure they play
> > nicely together, and they do.  (Yay!)  Assuming PFA passes I will include
> > those tests in the pipes branch before this one goes to a vote.
> >
> >
> FTR, there are several typos in the "Hello World" examples (*strto*t*upper,
> htmlent*i*ties*). Also, these examples will not work as written because
> explode() expects two arguments and will fail if you pass only one:
> https://3v4l.org/tLO0s. I wonder what the correct version of the pipe
> example (the one that uses strings as callbacks) would look like, given
> that you have to pass two arguments for explode()?

Hm.  You're right.  It used to, but it's been a very long time since explode() 
allowed an empty split, apparently.  I updated the example to use str_split, 
which is what I'd intended to do in this case.  Thanks.

If you wanted to explode with a separator in a non-PFA pipes world, you'd need 
to wrap it in an arrow function.  (Hence why a PFA-world pipe is all around 
better.)

--Larry Garfield

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



Re: [PHP-DEV] [RFC] Pipe Operator, take 2

2021-06-07 Thread Eugene Leonovich
On Mon, Jun 7, 2021 at 9:03 PM Larry Garfield 
wrote:

> Hi folks. Me again.
>
> A year ago, I posted an RFC for a pipe operator, |>, aka function
> concatenation.  At the time, the main thrust of the feedback was "cool,
> like, but we need partial function application first so that the syntax for
> callables isn't so crappy."
>
> The PFA RFC is winding down now and is looking quite good, so it's time to
> revisit pipes.
>
> https://wiki.php.net/rfc/pipe-operator-v2
>
> Nothing radical has changed in the proposal since last year.  I have
> updated it against the latest master.  I also updated the RFC to use more
> examples that assume PFA, as the result is legit much nicer.  i also tested
> it locally with a combined partials-and-pipes branch to make sure they play
> nicely together, and they do.  (Yay!)  Assuming PFA passes I will include
> those tests in the pipes branch before this one goes to a vote.
>
>
FTR, there are several typos in the "Hello World" examples (*strto*t*upper,
htmlent*i*ties*). Also, these examples will not work as written because
explode() expects two arguments and will fail if you pass only one:
https://3v4l.org/tLO0s. I wonder what the correct version of the pipe
example (the one that uses strings as callbacks) would look like, given
that you have to pass two arguments for explode()?

-- 
Thank you and best regards,
Eugene Leonovich