On Tue, Jul 18, 2023, at 5:08 PM, Karoly Negyesi wrote:
> My favorite pipeline is Elixir, where "The pipe operator |> passes the
> result of an expression as the first parameter of another expression".. But
> it works there because unlike with PHP, it's almost always the first
> argument you want. If it's not the first argument you needed to do some
> tricks which was only cleaned up in 2021 so now they do:
>
> 5
> |> then(&Enum.take(1..10, &1))
> |> Enum.reverse()
>
> but I digress.
>
> My problem here is... we actually need something that passes the RFC vote.
>
> What flexibility is missing here?

Please don't top post.

The main flexibility for callables is the ability to build a closure on the 
fly.  For example, using $$ (which Hack does, and I insist on calling T_BLING) 
means that for array and string functions you still need to worry about 
parameter order.  With a callable, you can effectively emulate Elixir's 
behavior if you want.

For example, my FP library has a whole bunch of higher order functions that 
just return pipe-ready functions:

https://github.com/Crell/fp/blob/master/src/array.php

Which, with a pipe operator, would allow for:

$result = $arr
  |> amap(trim(...))
  |> afilter(is_int(...))
  |> reduce(0, $fn)
  |> trim(...) // At this point it's a string and trim() is already unary, so 
we can just use it.
;

Which is pretty nice, IMO.  It "flows" nicely, supports both higher order 
functions and direct calls equally well, and allows for all kinds of further 
expansion that I haven't thought of yet.  

The Hack style would require thinking about the fact that array_map() and 
array_filter() take their arguments in reverse order from each other, which is 
just silly.  This way, that problem goes away entirely.

It also allows a pipe to be used as a quasi alternative to scalar methods, 
because (if we set aside visibility for the moment) a method is just a function 
with an implicit $this parameter.  Callables and higher order functions make 
that a lot cleaner.

The caveat is that it does add an extra step to use many of the existing array 
or string stdlib functions.  However, that's work that can be done once.  The 
link above is under 500 lines, heavily documented, and covers every array use 
case I've run into so far.  

Related improvements:

* Writing a higher order function right now is rather cumbersome.  There were 
two previous RFCs that would have made that vastly nicer (short-functions and 
auto-capture closures), but neither passed.  They would have allowed for:

function amap(callable $c) => fn (iterable $it): array {
    if (is_array($it)) {
        return array_map($c, $it);
    }
    $result = [];
    foreach ($it as $k => $v) {
        $result[$k] = $c($v);
    }
    return $result;
};

Which I think is pretty nice.

* PFA would give us the best of both worlds, as if you wanted you could do:

$result = $arr
  |> array_map(trim(...), ?)
  |> array_filter(?, is_int(...))
  |> array_reduce(?, $fn, 0)
  |> trim(...)
;

So with PFA and callable pipes, we get both options.  If pipe was just 
Hack-style, there would be no way to use higher order functions with it.

So IMO, the ideal experience that gets almost everyone what they want would be 
if all four of the following had passed:

https://wiki.php.net/rfc/short-functions
https://wiki.php.net/rfc/auto-capture-closure
https://wiki.php.net/rfc/partial_function_application
https://wiki.php.net/rfc/pipe-operator-v2

They are all mutually-complementary, but also useful on their own, and were 
designed that way deliberately.  Sadly, all four were declined.

So yeah, it's great that there's renewed interest in pipes, but I've already 
sunk a ton of time into this space (as have many other people that helped with 
those RFCs) with nothing to show for it.  Unless there's indication from a 
notable number of voters that they'd support it now, I'm reluctant to sink much 
more of my time (or anyone else's time) into something that has so far just run 
into brick walls.

If any of the above has convinced someone that we should try any of these 
features again, please speak up.  I seriously do want this functionality, but 
OSS spec work is not my favorite way to spend time.

--Larry Garfield

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

Reply via email to