rescript-lang / syntax

ReScript's syntax as a standalone repo.
MIT License
256 stars 38 forks source link

Treat await as an almost-unary operator. #711

Closed cristianoc closed 1 year ago

cristianoc commented 1 year ago

Making pipe behave just like application seems pretty unlikely. First -> has deep binary operator behavior, including associating to the left on a->b->c, and mixes in specific ways with other operators. Instead application lives on a different level entirely with no issues of how to treat specially the right-hand-side which is enclosed in parens (and lives in a radically different place in the call stack of the parser).

The await operator is essentially a unary operator. After all it takes one argument. It is also treated as such in JS. Some expected behaviours are that await 2 + await 3 just like -2 + -3 is expected to mean (await 2) + (await 3). Or: await getName() ++ await getSurname().

The issue raised by people who have tried await is in combination with pipe: the desired outcome is that await a->b is parsed as await (a->b). However notice that - a->b is parsed as (-a)->b, so that's a difference.

So on one side, one would like to have await behave like other unary operators. On the other side one wouldn't.

As a compromise, this PR treats await as an almost-unary operator. In the sense that it binds more tightly than any "real" binary operator such as + and **, but not -> and ..

This introduces some lack of uniformity, and requires special-casing parts of parsing and printing.

cristianoc commented 1 year ago

@cknitt this should be ready to go. Take a look: it should address the last comment on printing.