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.
;
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
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.
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."
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.
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#.
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?
52 comments
[ 4.4 ms ] story [ 63.8 ms ] thread1: https://kotlinlang.org/docs/extensions.html#extension-functi...
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 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
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.
$myString.trim().replace("w", "h");
Which has the advantage of also offering a clean alternative to the fragmented stdlib.
I believe they have solved this problem by now. Though no idea how.
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 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