On Monday, July 20th, 2026 at 14:55, Bob Weinand <[email protected]> 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 <[email protected]> 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 <[email protected]> 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

Reply via email to