====== PHP RFC: Pipe to return ====== * Version: 1.0 * Date: 2026-01-31 * Author: Vadim Dvorovenko, vadimon@mail.ru (vadim.dvorovenko@gmail.com) * Status: Under Discussion * Proposed Version: PHP 8.6 * Implementation: https://github.com/vadimonus/php-src/commits/pipe-to-return * Discussion thread: https://news-web.php.net/php.internals/129964 ===== Introduction ===== Piping result of expression to ''return'' keyword can be used to reduce congnitive complexity. // Current syntax return "Hello World" |> strlen(...); // New Syntax "Hello World" |> strlen(...) |> return; ==== The problem ==== Pipe operator introduced in [[pipe-operator-v3|RFC]] may lead to a complication in the perception of the flow due to mixing of left-to-right and right-to-left action directions. To avoid this, it is proposed to use the pipe operator for passing expression result to ''return''. Long-standing traditions of procedural code uses two main reading directions: top-to-bottom for procedural flow and right-to-left for function call and assignment flow in single line. The arrows indicate the reading direction, which follows the execution order. // Top-to-bottom $temp = "Hello World"; // -1-| // | $temp = htmlentities($temp); // <--| -2-| // | $temp = str_split($temp); // <--| -3-| // | $temp = array_map(strtoupper(...), $temp); // <--| -4-| // | return $temp; // <--| // Right-to-left // |-4-| |----------3---------| |-2-| |-1-| // V | V | V | V | return array_map(strtoupper(...), str_split(htmlentities("Hello World"))); The programmer's brain is tuned to perceive exactly these directions. When we try to reverse this directions, we need to to introduce additional rules, such as idents, to make hints to our brain that we should use bottom-to-top direction instead of top-to-bottom. // Bottom-to-top (requires idents) return // ^ // | array_map( // ^ // | strtoupper(...), str_split( // ^ // | htmlentities( // ^ // | "Hello World" ) ) ) ); Pipline operator and fluent pattern were invented to use top-to-bottom/left-to-right direction in function calls. Without assignments this gives perfect top-to-bottom and left-to-right code reading direction. // Pipeline "Hello World" |> htmlentities(...) |> str_split(...) |> (fn($x) => array_map(strtoupper(...), $x)) // Example with some fluent helper helper("Hello World") .htmlentities() .split() .map(fn($x) => strtoupper($x)); But things are getting worse, when we add return operator. We need to use top-to-bottom/left-to-righ reading direction for most parts of instruction, but bottom-to-top/right-to-left for last return action. // Single line case // |-------------------------------------------------------4-----------------------------------------------| // | |-----1----| |-----2-----| |------3---| | // V | V | V | V | return "Hello World" |> htmlentities(...) |> str_split(...) |> fn($x) => array_map(strtoupper(...), $x) // -| // Multiline case return // <---------------------------| // | "Hello World" // -1-| | // | | |> htmlentities(...) // <--| -2-| | // | | |> str_split(...) // <--| -3-| | // | | |> (fn($x) => array_map(strtoupper(...), $x)) // <-- -4-| In the case of multiple lines, the situation becomes more complicated for long functions and pipelines, when everything does not fit to one screen and to read one instruction it is necessary to scroll the screen up and down. The most natural and convenient reading direction for speakers of all LRT languages ​​(including but not limited to all languages ​​derived from Latin, such as English) is from left-to-right and top-to-bottom. With pipelining expression result to ''return'' keyword it would be posible to write code, that is read and perceived exactly this way, thereby reducing cognitive load. ===== Proposal ===== This RFC introduces of ability to use new pipe assignment operator with ''return'' keyword. expr |> return // equialent to return expr ==== Examples ==== Followind code is always read in one direction, and there is no need to look back. One line: "Hello World" |> htmlentities(...) |> str_split(...) |> (fn($x) => array_map(strtoupper(...), $x)) |> return; Multiple lines: "Hello World" |> htmlentities(...) |> str_split(...) |> (fn($x) => array_map(strtoupper(...), $x)) |> return; ===== Backward Incompatible Changes ===== Using ''|>'' with ''return'' currently causes syntax error. So it should not create backward incompatible changes. ===== Proposed PHP Version(s) ===== Next PHP 8.x ===== RFC Impact ===== ==== Perfomance ==== As new operator is just another syntax for assignemnt operator, it's usage should lead to exactly same bytecode, so no perfomance changes are expected. ==== To the Ecosystem ==== All language tools should be extended to use new syntax. ==== To Existing Extensions ==== Not affected ==== To SAPIs ==== Not affected ===== Future Scope ===== The ''return'' and ''throw'' keywords are only keywords leading to function exit. Using long chains of pipe operators for exceptions is unlikely pattern. However it is logical to repeat everything that relates to the ''return'' keyword for the ''throw''. On the other hand, since PHP 8 (see https://wiki.php.net/rfc/throw_expression), ''throw'' is operator and not statement as ''return''. So, operator precedence should be discussed. That's why, defferent RFC is planned for piping to ''throw''. ===== Voting Choices ===== Primary Vote requiring a 2/3 majority to accept the RFC: * Yes * No * Abstain ===== Patches and Tests ===== https://github.com/vadimonus/php-src/commits/pipe-to-return ===== Implementation ===== After the RFC is implemented, this section should contain: - the version(s) it was merged into - a link to the git commit(s) - a link to the PHP manual entry for the feature ===== References ===== * Discussion: https://news-web.php.net/php.internals/129964 ===== Changelog ===== * 2026-01-31 - Initial