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

Reply via email to