Reason: New Syntax Proposal for Infix or Pipe Operators

Created on 27 Nov 2016  路  13Comments  路  Source: reasonml/reason

I would like to propose a new syntax for the Infix or Pipe Operators

The Syntax in this proposal includes:
|>: Forward Function Application (This already exists in OCaml and in extension Reason)
<|: Backward Function Application

The inspiration is drawn directly from my experience and usage of Elm. Heres the docs from elm that concisely explains it:
screen shot 2016-11-26 at 10 23 02 pm

In my experience using both they we're really useful in making programs easier to reason about at a glance and the syntax made it really understandable how the values we're being passed/piped. I hope this opens discussion and feedback.

cc @jordwalke @chenglou

GOOD FIRST TASK

Most helpful comment

The problem with <| is that its precedence doesn't work as nicely as @@.

All 13 comments

I might be totally missing something, but isn't |> already in ocaml/reason and <| is the same as @@?
They seem to be both included in the pervasives library (https://caml.inria.fr/pub/docs/manual-ocaml/libref/Pervasives.html, under composition operators).
I only ask because I'm already a fan of using both 馃槢

@Schmavery those actually seem to do the same thing, however don't you think the <| makes more sense?

The problem with <| is that its precedence doesn't work as nicely as @@.

@hcarty That's exactly the kind of thing we can fix, however. I would like to know how people intend |> and <| to mix together in terms of precedence, and if they are left/right associative.

Right now, they have the same precedence and are left associative. @@ apparently has greater precedence. I suspect people would expect <| to have greater precedence too (which is consistent with the leading characters being analogous to arithmetic precedence. x || z < a (the < is evaluated first).

Should it be left or right associative?

x <| y <| z should be (x <| y) <| z correct? (Left associative).

We can create a precedence class in between INFIXOP0 and INFIXOP1 that holds infix identifiers that start with < or >. This would not be difficult. Does it solve the problem?

Marking as "good first task".

x <| y <| z should be (x <| y) <| z

This would make sense to me

I might have some time this week to work on this and submit a PR.

@jordwalke If you change operators that start with > it would change how >>= is interpreted, likely breaking/negatively affecting lots of monadic (Lwt, Async, etc) code.

There is already a special case for ** vs * so, arguably, one could make a similar special case for <| vs <.

@hcarty It would certainly change how >>= is parsed relative to |>. It won't technically "break" anything though because we can automate conversion between any two Reason parser versions (we just need to bump the version of Reason). It could negatively effect monadic code as you say, but it could just as easily improve, depending on your perspective. What is your opinion on the precedence change?

If anything beginning with < or > is given slightly higher precedence than
anything beginning with | (as it is with arithmetic/logical expressions) then:

For a monadic expression:

first 0 0 |> foo 1 2 >>= bar 3 4 |> baz 5 6

We would be changing the parsing from (today):

((first 0 0 |> foo 1 2) >>= bar 3 4) |> baz 5 6

To:

first 0 0 |> (foo 1 2 >>= bar 3 4) |> baz 5 6

We can certainly special case |> and <| as well, if you have a concrete proposal for their precedence relative to each other and everything else.

Here are the tradeoffs I see for each proposal:

  • Today: Everything with <, >, | is generally the same precedence, and groups "to the left". This is easy to learn/remember. Downside: You have to use () to group things "not to the left".

  • Proposal to make | lower precedence than <, >: The benefit is that it matches the intuitive precedence of logical operators everywhere else. The downside is that it's not always what you would want.

@jordwalke I'm leaning toward the proposed lower | based on your example. This parsing of your example is awkward and not likely to be the user's intent:

((first 0 0 |> foo 1 2) >>= bar 3 4) |> baz 5 6

As long as the following doesn't break I think I'm for the proposed change.

1 |> return >>= fun x ->
x + 1 |> return

Thank you for the detailed comments and example!

I don't see any big problem with tweaking the precedence of | (other than the fact that the aforementioned reason version converter doesn't exist yet afaik).

I'm a little confused about the precedence of <| though. @jordwalke suggested that it could be left-associative (unlike @@). The example that x <| y <| z should be (x <| y) <| z doesn't seem to match the example in the original description of the behaviour (unless I'm getting confused somehow).

The original description that @kennetpostigo gave of <| seems to be right associative?
leftAligned (monospace (fromString "code)) becomes leftAligned <| monospace <| fromString "code". So you'd want to evaluate fromString "code", pass that to monospace, and then pass the result to leftAligned. Seems like it would match the desired behaviour better (as well as be easier for people who are used to @@) if it were right-associative?

I feel like if it was left associative, you'd have to write something like leftAligned <| (monospace <| (fromString "code")), which seems to defeat the purpose..

@Schmavery Yes, it looks like in Elm, <| is right associative, and |> is left associative.

@jordwalke should I hold off on working on this until we reach a consensus on the operators side association and precedence? @Schmavery @hcarty Thanks you guys for the feedback and input 馃槉.

Sure. You can use |> today (and you can define <| as well let (<|) = (@@) - it just might not have perfect syntax/precedence until we decide what we'd like to do.

it's all parenthesis all the time these days :D

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rickyvetter picture rickyvetter  路  4Comments

shaneosullivan picture shaneosullivan  路  3Comments

ondrejsevcik picture ondrejsevcik  路  3Comments

TrakBit picture TrakBit  路  3Comments

jberdine picture jberdine  路  3Comments