Live data from Hacker News

PHP 8.5 adds pipe operator

thephp.foundation

141–150 of 282 posts

Re: PHP 8.5 adds pipe operator

#142
I had this argument in the PHP community when the feature was being discussed, but I think the syntax is much more complicated to read, requiring backtracking to understand. It might be easier to write.

Imagine you're just scanning code you're unfamiliar with trying to identify the symbols. Make sense of inputs and outputs, and you come to something as follows.

    $result = $arr
        |> fn($x) => array_column($x, 'values')
        |> fn($x) => array_merge(...$x)
        |> fn($x) => array_reduce($x, fn($carry, $item) => $carry + $item, 0)
        |> fn($x) => str_repeat('x', $x);
Look at this operation imaging your reading a big section of code you didn't write. This is embedded within hundreds or thousands of lines. Try to just make sense of what "result" is here? Do your eyes immediately shoot to its final line to get the return type?

My initial desire is to know what $result is generally speaking, before I decide if I want to dive into its derivation.

It's a string. To find that out though, you have to skip all the way to the final line to understand what the type of $result is. When you're just making sense of code, it's far more about the destination than the path to get there, and understanding these require you to read them backwards.

Call me old fashioned, I guess, but the self-documentating nature of a couple variables defining what things are or are doing seems important to writing maintainable code and lowering the maintainers' cognitive load.

    $values = array_merge(...array_column($arr, 'values'));
    $total  = array_reduce($values, fn($carry, $item) => $carry + $item, 0);

    $result = str_repeat('x', $x);

Re: PHP 8.5 adds pipe operator

#144
I'm confused about the rationale behind:

    |> fn($x) => array_column($x, 'tags')
Why is that inlined function necessary? Why not just

    |> array_column(..., 'tags')
?

I mean, I understand that it is because the way this operator was designed. But why?

Re: PHP 8.5 adds pipe operator

#145
post #142

I had this argument in the PHP community when the feature was being discussed, but I think the syntax is much more complicated to read , requiring backtracking to understand. It might be easier to write. Imagine you're just scanning code you're unfamiliar with trying to identify the symbols. Make sense of inputs and outputs, and you come to something as follows. $result = $arr |> fn($x) => array_column($x, 'values')…

I don’t disagree with your reasoning but I would have thought this pipe would be in an appropriately named function (at least that’s how I’d use it in Elixir) to help understand the result.

Re: PHP 8.5 adds pipe operator

#146
post #89

Earlier quoted context omitted.

They can't implement function application without tanking performance? I find that hard to believe. Especially considering that function application is already a commonly used (and, dare I say: essential) feature in the language, eg: `Math.sqrt(2)`. All we're asking for is the ability to rewrite that as `2 |> Math.sqrt`. What they're afraid of, my understanding goes, is that people hypothetically , may start leaning…

Your simple example (`2 |> Math.sqrt`) looks great, but when the code gets more complex, then the advantage of the pipe syntax is less obvious. For example, foo(1, bar(2, baz(3)), 3) becomes something like 1 (2, (3 |> baz) > bar), 3 |> foo or (3 |> baz) |> (2, % |> bar) |> (1, %, 3 |> foo) That looks like just another way to write a thing in JavaScript, and it is not easier to read. What is the advantage?

Uhm, don't do it, then. That's like arguing that the addition of the ternary operator is a bad one because not all if/else blocks look better when translated into it.

The goal is to linearlize unary function application, not to make all code look better.

Re: PHP 8.5 adds pipe operator

#147

The first typed programming language where I've seen pipe operator |> in action was in F#. You can write something like: sum 1 2 |> multiply 3 and it works because |> pushes the output of the left expression as the last parameter into the right-hand function. multiply has to be defined as: let multiply b c = b \* c so that b becomes 3, and c receives the result of sum 1 2 . RHS can also be a lambda too: sum 1 2 |> (f…

F# is excellent. It’s tooling, ecosystem, and compile times are the reason I don’t use it. I learned it alongside OCaml, and OCaml’s compilation speed spoiled me.

It is indeed a shame that F# never became a first class citizen.

Re: PHP 8.5 adds pipe operator

#148
post #2

Meanwhile the JS world has been waiting for 10 years for this proposal, which is still in stage 2 https://github.com/tc39/proposal-pipeline-operator/issues/23...

Best you'll git will be 3 new build systems and 10 new frameworks

Re: PHP 8.5 adds pipe operator

#149
post #112
post #91

I'm surprised that the example requires lambdas... What's the purpose of the `|> foo(...)' syntax if the function has to take exactly one operand? Why is it necessary to write this? $arr |> fn($x) => array_column($x, 'tags') Why doesn't this work? $arr |> array_column(..., 'tags') And when that doesn't work, why doesn't this work? $arr |> array_unique

Apparently "foo(...)" is just the PHP syntax for a function reference, according to the "first-class callable" RFC [1] linked from the article. So where in Python you would say e.g. callbacks = [f, g] PHP requires the syntax $callbacks = [f(...), g(...)]; As for the purpose of the feature as a whole, although it seems like it could be replaced with function composition as mentioned at the end of the article, and the…

Thanks, that makes sense!

Re: PHP 8.5 adds pipe operator

#150
post #25

Earlier quoted context omitted.

PHP has traits, just invent that API, put it in a trait and add it to your data classes.

How would that work if a library supplies a function that takes a string and returns an array? I can’t make it use my array class.

Could you give a realistic example?

The PHP pipes as described in the articles about it will require a bunch of wrapping anyway so you could just do that. There are several alternatives, from a function or method that just converts from raw array to class, to abstractions involving stuff like __invoke, __call, dispatchers and such.

Also the expectation to not have to put facades on libraries is a bit suspicious, in my experience it is very common. I find it unlikely you actually want to use raw arrays instead of leveraging type guards in your code.

Post reply on HN