On Thu, Aug 21, 2025, at 4:07 AM, Hans Krentel wrote: > On Thursday 14 August 2025 21:30:08 (+02:00), Larry Garfield wrote: > >> Does anyone have a better solution to suggest? > > I've been following the discussion on the pipe/short-closure precedence > issue, and while the parentheses-based solution works, it does lead to > syntactic noise that undermines the readability benefits of pipes. > > I'd like to suggest an alternative that turns this problem into an > opportunity for a more elegant syntax. > > Inspired by prior art like Haskell's `do` notation, I propose what I > call "short closure canned pipes." The idea is to leverage the greedy > nature of short closures to define a clean, linear pipe chain within a > closure context. Instead of fighting the precedence, we embrace it to > create a new form: > > > Current problematic example (even with parentheses): > ---------------------------------------------------- > > fn($x) => ($x > |> (fn($x) => array_map(strtoupper(...), $x)) > |> (fn($x) => array_filter($x, fn($v) => $v != 'O')) > ); > > Proposed "canned pipes" syntax: > ------------------------------- > > fn($x) => > |> array_map(strtoupper(...), $x) > |> array_filter($x, fn($v) => $v != 'O') > ; > > > This syntax: > > * Resolves the ambiguity: The `fn($x) =>` explicitly "cans" the value > for the entire pipe chain, making the precedence clear without > parentheses. > > * Reduces boilerplate: It eliminates the repetition of `fn($x) =>` and > nested parentheses, making the code more readable and maintainable. > > * Aligns with intent: It reads as a simple sequence of transformations, > which is the core goal of the pipe operator. > > This approach effectively provides syntactic sugar for the common case > of processing a value through a pipe chain within a closure. It turns > the late-discovered defect into a win for developer ergonomics and > future-proofing. > > I understand that implementation feasibility needs to be assessed, but > if possible, this could be a more satisfying solution than mandatory > parentheses. Thanks to the team for highlighting this issue -- it's > sparked a creative way to enhance the feature. > > Would love to hear thoughts on this. > > Best, > hakre
That's an interesting idea, but I don't think it solves the problem. It would make the syntax for pipes-in-closures nicer, yes. However: 1. Ideally, I'm hoping such a pipe-in-closure is replaced with a Composition operator soon enough (https://wiki.php.net/rfc/function-composition), so that wouldn't even be necessary. 2. The main problem is not when a pipe is inside a closure, but when a closure is inside a pipe, which is likely the far more common case. $input |> fn($x) => array_map(strtoupper(...), $x) |> fn($x) => array_filter($x, fn($v) => $v != 'O') ; The problem is this gets interpreted "backwards", with the first closure wrapping around second, rather than being a sibling of it in a pipe chain. A short-hand for pipes-in-closures wouldn't address this issue, which is the more pressing concern. The annoying extra parens there would also be resolved using PFA, which side steps the arrow function in the common case. As the issue is the syntactic parsing of arrow functions, not having arrow functions would also resolve the issue. (As would using higher-order functions instead, which frankly is what I am likely to do 90% of the time myself.) --Larry Garfield