Re: [RFC] Pipe Assignment Operator

From: Date: Tue, 21 Jul 2026 04:18:28 +0000
Subject: Re: [RFC] Pipe Assignment Operator
References: 1 2 3 4 5  Groups: php.internals 
Request: Send a blank email to internals+get-132063@lists.php.net to get a copy of this message
On Monday, July 20th, 2026 at 14:55, Bob Weinand <bobwei9@hotmail.com> wrote: > I just have one more question to the RFC author, which I see in the > implementation, but the RFC is not explicitly noting: > Is it intentional that fetching is repeated? > It will literally desugar $a->b->c |>= strtolower(...); to > $a->b->c = strtolower($a->b->c); resulting in double execution > of e.g. property get hooks. On Monday, July 20th, 2026 at 15:24, Tim Düsterhus <tim@bastelstu.be> wrote: > I would consider that a bug in the implementation, given that the > "Single-Evaluation Guarantee" section mentions: > > When the LHS contains sub-expressions, they are evaluated > exactly once: > > Thus if it behaves differently to ??=, it's a bug in the > implementation :-) Hi Bob, Tim, Thanks for flagging this. I tested the scenario Bob described and |>= behaves identically to ??= here: class Inner { public string $c = "hello" { get { echo "Inner::c GET\n"; return $this->c; } set(string $v) { echo "Inner::c SET\n"; $this->c = $v; } } } class Outer { public Inner $b { get { echo "Outer::b GET\n"; return $this->b; } } public function __construct() { $this->b = new Inner(); } } $a = new Outer(); $a->b->c |>= strtoupper(...); // Outer::b GET (read) // Inner::c GET (read) // Outer::b GET (write-back) // Inner::c SET (write-back) $a->b->c ??= "default"; // Outer::b GET (read) // Inner::c GET (read) // Outer::b GET (write-back) // Inner::c SET (write-back) Both |>= and ??= fetch the intermediate chain twice (once for the read, once for the write-back). The single-evaluation guarantee in the RFC refers to sub-expressions like $arr[expensive_call()], where the call itself is evaluated only once. That works correctly: $arr[track()] |>= strtoupper(...); // track() is called exactly once So the behavior is consistent with ??=. Bob, your observation about optimizing intermediate chain fetches with ad-hoc references is interesting, but that would be an improvement to all compound assignment operators, not something specific to |>=. I've updated the RFC to clarify this in the Single-Evaluation Guarantee section. On Sunday, July 19th, 2026 at 08:35, Nick Sdot <php@nicksdot.dev> wrote: > 1) my point is: why |>= and not > =|>? Hi Nick, Tim already covered this well, but I agree with him: |>= follows the established op= convention for compound assignments (+=, .=, ??=). =|> looks like a special form of => rather than an assignment, and consistency with existing patterns is worth more than theoretical future extensibility for operators that may never materialize. > 2) Holly's example without semicolons Yeah, that was just a missing semicolon in the email example; standard parse error, same as with |>. Nothing to address there. > 3) I recently discovered a bug [1] when pipes are combined with > property hooks. Thanks for flagging this. I've added a test (assign_pipe_018.phpt) that covers |>= with get/set hooks, virtual properties, and readonly properties. The |>= side works correctly; the bug you found (#22587) is specific to the base |> operator and is not introduced or affected by this RFC. Thanks for testing the implementation and for the detailed feedback! Best, Caleb

« previous php.internals (#132063) next »