52 comments

[ 4.4 ms ] story [ 63.8 ms ] thread
While I appreciate the effort and like the approach in general, in this use case I really would prefer extensions / extension functions (like in Kotlin[1]) or an IEnumerable / iterator approach (like in C#).

  $arr = [
    new Widget(tags: ['a', 'b', 'c']),
    new Widget(tags: ['c', 'd', 'e']),
    new Widget(tags: ['x', 'y', 'a']),
  ];
  
  $result = $arr
      |> fn($x) => array_column($x, 'tags') // Gets an array of arrays
      |> fn($x) => array_merge(...$x)       // Flatten into one big array
      |> array_unique(...)                  // Remove duplicates
      |> array_values(...)                  // Reindex the array.
  ;
feels much more complex than writing

  $result = $arr->column('tags')->flatten()->unique()->values()
having array extension methods for column, flatten, unique and values.

1: https://kotlinlang.org/docs/extensions.html#extension-functi...

raku has had feed operators like this since its inception

  # pipeline functional style
  (1..5)
    ==> map { $_ * 2 }
    ==> grep { $_ > 5 }
    ==> say();              # (6 8 10)

  # method chain OO style
  (1..5)
    .map( * * 2)
    .grep( * > 5)
    .say;                   # (6 8 10)
uses ==> and <== for leftward

true it is syntax sugar, but often the pipe feed is quite useful to make chaining very obvious

https://docs.raku.org/language/operators#infix_==%3E

I like it.

I really believe the thing PHP needs the most is a rework of string / array functions to make them more consistent and chain able. Now they are at least chainable.

I'm not a fan of the ... syntax though, especially when mixed in the same chain with the spread operator

C'mon Dart! Follow up please. Go is a lost cause...
The stdlib is so inconsistent this will be a nightmare.

Optionally with a better language you know what order params as passed (array_map / array_filter), but in PHP its an coin toss.

This feels very bolted on and not suited for the stdlib at all.

PHP devs should instead FIRST focus on full unicode support (no, the mb_real_uppercase wont do), and only then focus on a new namespaced stdlib with better design.

Why doesn't PHP remove the horrid $ symbol for variables and the -> symbol for calling methods? I think those alone would do a lot more for its perception and adoption than adding the pipe operator.
PHP has its significant flaws, but superficial syntactic differences aren't among them. In my experience, it takes two weeks to get used to pretty much any syntax.
Why not just make types psuedo-objects?

$myString.trim().replace("w", "h");

Which has the advantage of also offering a clean alternative to the fragmented stdlib.

I tried to emulate something similar with PHP at one point. But the problem with PHP was parameter order. Especially in functions like array_key_exists() the array element is the 2nd parameter, while pipe operator expects the object to work on be the 1st parameter, the array in these cases.

I believe they have solved this problem by now. Though no idea how.

"A major limitation of the pipe operator is that all the callables in the chain must accept only one required parameter.

For built-in functions, if the function does not accept any parameters, it cannot be used in a chain. For user-land PHP functions, passing a parameter to a function that does not accept any parameters does not cause an error, and it is silently ignored.

With the pipe operator, the return value of the previous expression or the callable is always passed as the first parameter to the next callable. It is not possible to change the position of the parameter."

https://php.watch/versions/8.5/pipe-operator

In the light of these limitations I would not call the Elixir implementation "slightly fancier".

I'm not so sure I'll be upgrading my local PHP version just for this but it's nice that they are adding it, I'm sure there is a lot of library code that would look much better if rewritten into this style.

i wish python had something liek that to be honest
I love the pipe operator - one of the things I dig about Elixir though many languages have it. It's so much easier to reason about:

  $result = $arr
    |> fn($x) => array_column($x, 'tags')
    |> fn($x) => array_merge(...$x)
    |> array_unique(...)
    |> array_values(...)
VS array_values(array_unique(array_merge(...array_column($arr, 'tags'))));
This will be the year of PHP. People are tired of JS.
The syntax is ugly as hell.
(comment deleted)
composition would be much nicer than this, maybe soon
Every single one of those steps buffers into a temporary variable - this isn't efficient like a bash pipe.
Rust is next? Jokes aside, pipe operators in programming languages have a interesting side effect of enabling railway oriented programming that I miss the most when not working in F#.
Am I the only one who found it ugly?
PHP is that weird beast that no one wants to praise and yet it works tremendously well for those who manage to tame it.

I would likely never touch it as there are too many languages to use and what I know is more than enough to do my job, but I am super excited to see languages like PHP that aren't mainstream in my bubble to keep evolving

It's lovely to see how PHP keeps growing. It's far from what it was when I used to code with it in V3. I really thought it would be lost in its bad design, but the core devs kept at it, and it is, indeed, a pretty decent language now.
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