Jordi Kroon:
I like the general direction and I am not fully against the idea. That
said, I am hesitant to introduce another way to express the same
thing, especially when it affects readability.
When we are speaking about pipe operator, it all looks as trying to
introduce another way to express the same thing, and it affects readability.
As for me,
$temp = "Hello World";
$temp = htmlentities($temp);
$temp = str_split($temp);
$temp = array_map(strtoupper(...), $temp);
return $temp;
and
return array_map(strtoupper(...), str_split(htmlentities("Hello
World")));
were quite effective ways of expressing value transformation flow. But
that RFC was adopted. My RFC is an attempt to quickly eliminate the
cognitive side effects arisen by adding the pipe operator to the language.
The addition of the pipe operator didn't immediately force all language
users to use it. But it did give them the option. Which method
of expression of same thing sould be used in different cases, most
likely will be described later in the coding standards of specific
projects. Likewise, the method proposed here will not be mandatory for
use, but there may be cases where it will be chosen for greater readability.
More importantly, I do not think the responsibility for returning
should live inside the pipe. Returning is control flow, while the
pipe’s core purpose is transforming data. With this change, the pipe
no longer clearly communicates “transform this value,” but can instead
become responsible for ending execution. I would rather see the pipe
produce a result, and keep the return outside the pipe so the intent
stays explicit.
Also, while the example below obviously would not work, it highlights
the potential ambiguity this introduces. In a long pipeline, it
becomes less clear where returning happens and what role the pipe is
playing.
function giveMeFourtyTwo() {
return 42
|> return;
}
Also if you put this into the short `fn` syntax. It will break for the
same reasons as above.
fn () => 'hello world'
|> strlen(...)
|> return;
Our language is now very flexible. But such flexibility would be
impossible if everithing was strictly divided into categories. Take the
`throw`, for example. It's obviously intended for flow control. However,
it can be used anywhere, like in following example.
return 42 |> fn($val) => throw new RuntimeException($val);
// or
throw throw throw new Exception();
Although such a statements contains ambiguity between return and throw,
or between multiple throws, we don't criticize the language for this
possibility. In such cases, we say the author of the code has chosen an
unfortunate style of expression.
My proposal, on the contrary, does not allow using two types of return
in one expression or using return inside an arrow function. In this
sense, my proposal is quite strict.
You can use either way of expression, but not both at the same time.
Thus, ambiguity is generated not by the programming language itself and
its capabilities, but by those who express their thoughts in it. We
should not limit the expressive instruments of a language simply out of
fear that they will be misused.
--
Vadim Dvorovenko