The Pipe Operator

Read the RFC Externals
87
253 yes
119 no

The "pipe operator" |> allows you to chain multiple function calls in a more convenient way.

$result = "Hello World"
    |> 'htmlentities'
    |> 'str_split'
    |> fn($x) => array_map('strtoupper', $x)
    |> fn($x) => array_filter($x, fn($v) => $v != 'O');

This RFC was already declined, but we're sharing it here as another test RFC, and because it'd be interesting to learn people's opinion about it.

Click the bar to cast your vote!
68%
32%
2

I've been waiting for pipe operators in a very long time.

Share:
terremoth avatar
terremoth
voted yes
1

So much energy invested into some messy code, where not even 'htmlentities' can be found by IDE, as it's a string. Why is the following edge-case (!) not convenient enough?

$result = "Hello World";
$result = htmlentities($result);
$result = str_split($result);
$result = array_map('strtoupper', $result);
$result = array_filter($result, fn($v) => $v != 'O');

or

$result = strtoupper(htmlentities("Hello World"));
$result = array_filter(str_split($result), fn($v) => $v != 'O');
Share:
mansurs avatar
mansurs
voted no
1
  • This syntax is in my opinion not really an advantage, especially with the hacky way to specify the callbacks (not even/especially not with the first class callable syntax).
  • The argument positions are not consistent enough to support calls like this
  • Passing additional arguments (like limiting the str_split, or specifying flags for htmlentities in the example) is not possible (or either will be really difficult to read, or will require to wrap it in arrow functions).

In classic PHP this is totally fine to read:

$input = 'Hello World';

$encoded = htmlentities($input, double_encode: false);
$list = str_split($encoded);
$uppercased = array_map(strtoupper(...), $list);
$result = array_filter($uppercased, fn($v) => $v !== '0'));
Share:
im-a-teapot avatar
im-a-teapot
voted no
1

We should accept any RFC increasing the capacity of PHP to design things elegantly. Which is done by this suggestion.

I voted "Yes".

PHP misses linear function composition... until now.

Share:
trehinos avatar
trehinos
voted yes
1

I find this syntax pretty messy, to be frank. Maybe it's a good idea (since it is available in "modern languages"), but not something I would use much or even recommend using...

Share:
jhonatanjacinto avatar
jhonatanjacinto
voted no
1

Imagine, having chainable functions like Laravel collections inside php

$result = collect("Hello World")
    ->map(fn($x) => htmlentities($x))
    ->map(fn($x) => str_split($x))
    ->map(fn($x) =>  array_map('strtoupper', $x))
    ->map(fn($x) =>  array_filter($x, fn($v) => $v != 'O'));
		
$result = "Hello World"
    |> 'htmlentities'
    |> 'str_split'
    |> fn($x) => array_map('strtoupper', $x)
    |> fn($x) => array_filter($x, fn($v) => $v != 'O');
		

That would be so useful. Not to mention about pipeline pattern, which can be implemented with this, so easy. I do like First-class callable syntax.

Share:
uchm4n avatar
uchm4n
voted yes
1

It would make chaining arguments easier to read, but that it. No good control over the exact output and it is really different from the PHP programming way. For me its more a maybe.

Share:
MarcHagen avatar
MarcHagen
voted yes
1

i think php should have more build in support for functional programming concepts so pipe operator looks like a good idea to me. i do agree that the syntax maybe needs some work.

Share:
gertvdb avatar
gertvdb
voted yes
1
Share:
undjike avatar
undjike
voted yes
1

Pipes are common in many languages and aren't an unfamiliar concept. Whilst there are packages, like Laravel's pipelines, that implement a way to achieve this, this syntactic sugar makes it easy to implement lightweight code for performing a simple series of actions on a subject.

Share:
sam-moffat avatar
sam-moffat
voted yes
1

You could do this simply enough in userland code

pipe(
		'Hello world',
		htmlentities(...),
		'str_split',
		fn($x) => array_map('strtoupper', $x),
		fn($x) => array_filter($x, fn($v) => $v != 'O'),
);
function pipe(...$pipes) {
    $result = array_shift($pipes);
    foreach ($pipes as $pipe) {
        $result = $pipe($result);
    }

    return $result;
}
Share:
letssurf avatar
letssurf
voted no
1

I do not like this syntax at all and have no problem with user-land solutions.

Share:
eigan avatar
eigan
voted no
1

My chief complaint about the syntax is it blocks functions with multiple parameters. This kneecaps the piping capability, and you're forced back into inside-out calls, or stopping a pipe to call a prohibited function, then start a new pipe with that result.

The operator itself |> is fine, and to me it reads easily as one expression sending a value forward. What i dislike is the representation of the right-side callable: " Hello world " |> 'trim' or "Hello world" |> [$object, 'method'] ... In my opinion, the language already has too much of this workaround syntax.

First-class callable syntax " Hello world " |> trim(...) is helpful in that regard, but still falls apart when multiple arguments are needed.

Share:
thookerov avatar
thookerov
voted no
1

Generally YES, but with some minor change that would allow skipping defining function, so instead of:

$result = "Hello World"
    |> htmlentities(...)
    |> str_split(...)
    |> fn($x) => array_map(strtoupper(...), $x)
    |> fn($x) => array_filter($x, fn($v) => $v != 'O');

I'd rather see something like

$result = "Hello World"
    |> htmlentities(...) // or htmlentities(?)
    |> str_split(...)
    |> array_map(strtoupper(...), ?)
    |> array_filter(?, fn($v) => $v != 'O');
Share:
jacek avatar
jacek
voted no
1

This looks like a problem that would be better-solved with a first-party object-oriented API for primitive types (a bit like JavaScript). Honestly the syntax looks a bit odd and as per the example, referencing global functions as strings is an anti-pattern IMO (not friendly for IDEs / refactoring!).

For example:

$result = ("Hello World") // string
    ->htmlentities(...)
    ->split(...) // array
    ->map(fn ($x) => strtoupper($x))
    ->filter(fn($v) => $v != 'O');
Share:
uphlewis avatar
uphlewis
voted no
RSS Feed Contribute Watch on YouTube Our License
© 2024 RFC Vote. This project is open source. Contribute and collaborate with us!