Skip to content
This repository has been archived by the owner on Jun 15, 2023. It is now read-only.

Treat await as an almost-unary operator. #711

Merged
merged 5 commits into from
Oct 31, 2022
Merged

Conversation

cristianoc
Copy link
Contributor

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.

Making pipe behave 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.

The await operator is essentially a unary operator. After all it takes on 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)`.

The issue raised is 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 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 more than `->` and `.`.

This introduces some lack of uniformity, and requires special-casing parts of parsing and printing.
@cristianoc cristianoc changed the title Treat await as an almost unary opeator. Treat await as an almost-unary operator. Oct 29, 2022
@cristianoc
Copy link
Contributor Author

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

@@ -175,7 +175,11 @@ let flattenOperandRhs parentOperator rhs =
| _ when ParsetreeViewer.isTernaryExpr rhs -> true
| _ -> false

let lazyOrAssertOrAwaitExprRhs expr =
let binaryOperatorInsideAwaitNeedsParens operator =
ParsetreeViewer.operatorPrecedence operator
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a behind history? it seems different from Res_token.precedence.

Copy link
Member

@cknitt cknitt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works fine now! Thanks a lot!

@cristianoc cristianoc merged commit b69c5e0 into master Oct 31, 2022
@cristianoc cristianoc deleted the await_almost_unary branch October 31, 2022 09:10
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants