Reason: Fast pipe new syntax `->` doesn't seem to replace old syntax `|.` some times

Created on 27 Oct 2018  路  6Comments  路  Source: reasonml/reason

It's originally discussed here

I found something interesting and it's probably a bug.

-> doesn't work after |> when |. still works after |>

click to see the proof

code for the proof

/* this works */
"1=2=3"
  |> Js.String.split("=")
  |. Js.log;

/* this works, too */
"1=2=3"
  -> Js.log;

/* but the code below doesn't */
/* you can test this with uncommenting
"1=2=3"
  |> Js.String.split("=")
  -> Js.log;
*/

ReasonML ver: 3.3.2

Syntax

Most helpful comment

this is because -> isn't just sugar for |., it has a higher precedence.

"1=2=3"
  |> Js.String.split("=")
  -> Js.log;

is parsed as

"1=2=3"
  |> (
     /* the following expression logs the curried function, and returns unit, not a function */
    Js.String.split("=") |. Js.log
  );

which is a type error, you need to wrap the expression in parens:

("1=2=3" |> Js.String.split("="))
  -> Js.log;

if you reformat the correct example with |., that's what you'll get.

All 6 comments

this is because -> isn't just sugar for |., it has a higher precedence.

"1=2=3"
  |> Js.String.split("=")
  -> Js.log;

is parsed as

"1=2=3"
  |> (
     /* the following expression logs the curried function, and returns unit, not a function */
    Js.String.split("=") |. Js.log
  );

which is a type error, you need to wrap the expression in parens:

("1=2=3" |> Js.String.split("="))
  -> Js.log;

if you reformat the correct example with |., that's what you'll get.

Yes, for now -> has higher precedence than |..

("1=2=3" |> Js.String.split("="))->Js.log;

This is indeed the correct solution.
Will leave this open, the precedence of -> is pretty counterintuitive.
I think we can address this.

@bloodyowl thanks for the good explanation.
@IwanKaramazow Yes, I agree it can be counterintuitive unless the code writer know how actually -> works as described by @bloodyowl.

So I hope it should either the explanation to be added in the document page or the fast pipe works more intuitive to avoid the confusion.

And I personally hope to see -> gets to work just like |. to be able to code simpler.

AFAIK the main motivation for the precedence is to be able to do things like event->target##value and value->getWithDefault(x).name

Is there any way to preserve |. when using refmt?
When a chain has a mix of -> and |> code becames ugly.

Closing as "won't fix", as the precedence is by design.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

TheSpyder picture TheSpyder  路  3Comments

rickyvetter picture rickyvetter  路  4Comments

bobzhang picture bobzhang  路  3Comments

modlfo picture modlfo  路  4Comments

chenglou picture chenglou  路  3Comments