Pipe Operator
This is actually part of an ongoing sequence of syntax improvements that started back with $a = foo(...); for creating closures. There is more to come in this area.
Back in the day, I inflicted something like
$file = array_map(fn($line) => explode(' ', $line), array_values(
array_filter(
array_map(trim(...),
preg_split('/\b0\b/',
join(' ',
array_map(collapse_space(...),
array_map(trim(...),
preg_grep('/^\s*-?\d+(\s+-?\d+)*\s*$/',
preg_grep('/^[a-z]/',
file($filename),
PREG_GREP_INVERT))))),
flags: PREG_SPLIT_NO_EMPTY)),
strlen(...))));
on you all. Notice how far some of the arguments end up from the function call they're actually part of.
The somewhat more sane way of doing it involves repeatedly reusing the variable:
$file = file($filename);
$file = preg_grep('/^[a-z]/', $file, PREG_GREP_INVERT);
$file = preg_grep('/^\s*-?\d+(\s+-?\d+)*\s*$/', $file);
$file = array_map(trim(...), $file);
$file = array_map(collapse_space(...), $file);
$file = join(' ', $file);
$file = preg_split('/\b0\b/', $file, flags: PREG_SPLIT_NO_EMPTY);
$file = array_map(trim(...), $file);
$file = array_filter($file, strlen(...));
$file = array_values($file);
$file = array_map(fn($line) => explode(' ', $line), $file);
With the pipe operator that becomes
$file = file($filename)
|> (fn($ls) => preg_grep('/^[a-z]/', $ls, PREG_GREP_INVERT))
|> (fn($ls) => preg_grep('/^\s*-?\d+(\s+-?\d+)*\s*$/', $ls))
|> (fn($ls) => array_map(trim(...), $ls))
|> (fn($ls) => array_map(collapse_space(...), $ls))
|> (fn($ls) => join(' ', $ls))
|> (fn($ls) => preg_split('/\b0\b/', $ls, flags: PREG_SPLIT_NO_EMPTY))
|> (fn($ls) => array_map(trim(...), $ls))
|> (fn($ls) => array_filter($ls, strlen(...)))
|> array_values(...)
|> (fn($ls) => array_map(fn($line) => explode(' ', $line), $ls));
Still a bit verbose, but like I say the syntax changes are a work in progress. Also note that the whole pipeline is, like the original nested functions but unlike the repeated assignment statements, a single expression; I could have started the pipeline with $file = !file_exists($filename) ? '' : file($filename) |> ....