Re: [PHP-DEV] [RFC] Pipe Assignment Operator

[email protected] (Nick Sdot) Sun, 19 Jul 2026 15:35:38 +0700
Newsgroups php.internals
Message-ID <[email protected]>
Hey Caleb,

On 10.07.26 11:45, Caleb White wrote:
> Hi internals,
>
> I'd like to open discussion on my (first!) RFC for the pipe assignment operator (|>=):
> https://wiki.php.net/rfc/pipe_assignment_operator
>
> It adds a compound assignment form of the pipe operator, so that
> $x |>= callable is shorthand for $x = $x |> callable, with
> support for chaining. Implementation with tests is at:
> https://github.com/php/php-src/pull/22633
>
> Looking forward to your feedback.
>
> Thanks!
> Caleb

Thanks for the RFC! As you already could guess I am in support. Been 
running your implementation and didn't run into anything unexpected, nor 
was I able to break it in different ways than the current pipe 
behaviour. Though, I'd like to add the following.

1) This was feeling nitpicky at first, but it doesn't leave me alone 
since I first read your RFC. :) Now, given what Vadim added to the 
discussion, I think it is worth bringing it up. Right now we are doing:


```
$someVar = $someVar |> array_filter(...);
```

the RFC allows to omit the noise:

```
$someVar =                    |> array_filter(...);
```

you see where I am going; now let's remove the white space:

```
$someVar =|> array_filter(...);
```

my point is: why `|>=` and not `=|>`?

I think the latter would be more intuitive: assign the result of piping 
to the variable. I know that `|>=` follows the established `foo=` 
convention for compound assignments like `??=` or `.=`; which is an 
argument in its favour. Still, I think `=|>` better communicates how 
this particular operation expands. Especially when considering future 
additions like the ones Vadim proposes in future scope.

Because a side effect of having `=|>` would be that the right hand side 
of `|>` remains open to extension for potential in-pipe-behaviour 
modifying features like the ones Vadim proposes -- without the final 
assignment being affected. As in, `=|>` assigns the pipe result, while 
`=|>+`, `=|>-`, `=|> .`, `=|>whatever` allow modifying in-pipe 
behaviour. This would make sense because perhaps these pipe behaviour 
operators will also be allowed for non-shorthand assigned (`|>+`, `|> 
-`, `|> .` ) pipes that want the resulting immutable right hand side 
Larry made an argument for. Having a clear separation between 
assignment, and potential future additions to modify pipe behaviour 
makes sense. As in, want to add a modifying operator later? Cool, your 
assignment remains in tact `=|>`. You just add a modifying operator 
`=|>-` instead of flipping from `|>=` to `|>-=` which would affect final 
assignment *and* in-pipe behaviour -- having the modifier out of the 
final assignment decision is cleaner.

Also, it is not impossible that what Vadim proposes in future scope 
would result in something like `|>=??=` which IMO makes an even stronger 
point for strictly separating what is proposed here and potential future 
additions of modifying operators: `=|> .. |> ??=`. Because these *are* 
different: `... |> ??=` (for in-pipe operations) and `=|> ... |> ??=` 
(only for the final assignment). Vadims proposal makes sense on it's 
own, but it currently mixes two concerns: in-pipe operations and final 
assignment -- which I believe should be separated. Both of your 
proposals (especially Vadims future scope) should probably rather 
complement each other instead of competing; I think what I am writing 
here potentially could make this easier.

One additional soft argument is that text ligatures will show >= as ≥ 
which will just add to the confusion if modifying operators as Vadim 
proposes in future scope would ever be added.

Long story short: `=|>`over `|>=` IMO has a lot of appeal.

Though, I know not having `|>=` would deprive us of the "volcano 
operator" naming; sorry for being the party pooper.

2) Holly brought up this example:

```
$foo |>= a(…)
$foo |>= b(…)
$foo |>= c(…)
```

and it seems you talked past each other. Hollys example didn't end lines 
with semicolons, while your answer had them. Currently, the 
non-semicolon variant:

```
$foo = "hello";
$foo |>= strtoupper(...) // no semicolon
$foo |>= strtolower(...);
var_dump($foo);

```

throws with "Parse error: syntax error, unexpected variable "$foo" in". 
In the same way the current

```
$foo = "hello";
$foo |> strtoupper(...) // no semicolon
$foo |> strtolower(...);
var_dump($foo);
```

throws. I just wanted to point this out because apparently it caused 
confusion in the discussion. Perhaps worth to clarify the RFC (even 
though it's also current pipe behaviour).

3) I recently discovered a bug [1] when pipes are combined with property 
hooks. Unsurprisingly, with your addition it is the same. However, since 
this shows that pipes are not behaving everywhere identical it would 
probably be good to add some tests to confirm the interaction of 
assigned pipes with property hooks, readonly etc. -- and maybe also to 
clarify it in the RFC.


---

Cheers
Nick

[1] https://github.com/php/php-src/issues/22587