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

Reply via email to