Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add syntax sugar that translates ? to Result.try #6828

Closed
smores56 opened this issue Jun 22, 2024 · 3 comments
Closed

Add syntax sugar that translates ? to Result.try #6828

smores56 opened this issue Jun 22, 2024 · 3 comments
Labels
can Canonicalization enhancement New feature or request intermediate issue Likely good for someone who has completed a few other issues parsing

Comments

@smores56
Copy link
Sponsor Collaborator

Issue following from discussion in Zulip chat.

We want to add Rust's try operator, the ?, to Roc, making early returns on Err cleaner. This will work just like ! works when it desugars to Task.await.

There are many benefits to having ? added to Roc, including "flatter" code, better readability, and better concision, but these could also be achieved if ! was extended to work for Results or even anything implementing a hypothetical AndThen ability. However, the mental overhead of understanding that a return type's AndThen implementation is being leveraged, as well as the teach-ability damage to the language, make generalizing the ! operator cost-prohibitive. By having ! just for Tasks and ? just for Results, we get the cleanliness benefits of each operator without making the language much harder to learn, and we prevent potential exploitation of a generalized ! operator.

This also paves the way for the eventual deprecation and removal of backpassing from the language.

Some things we should consider when implementing this operator:

  • It will work almost exactly like the ! operator, but will instead translate to Result.try every time
  • The error messages we generate on type errors will not only need to handle when the value ? is used on isn't a tag union, but also if there are extra or missing variants from [Ok _, Err _]
@lukewilliamboswell lukewilliamboswell added enhancement New feature or request parsing can Canonicalization intermediate issue Likely good for someone who has completed a few other issues labels Jun 23, 2024
@sekerez
Copy link
Contributor

sekerez commented Jun 26, 2024

Would love to have a go at this! Looking into it, will provide an update

@lukewilliamboswell
Copy link
Collaborator

I can give you some good pointers on this.

First step is to implement a new variant in crates/compiler/parse/src/ast.rs, probably something like ResultTryQuestion or something, that is almost identical to TaskAwaitBang(&'a Expr<'a>).

You should add some snapshot tests in crates/compiler/test_syntax/tests/snapshots/pass and confirm it parses correctly.

That is probably one PR.

Then the next step is to desugar it, which I've nicknamed "unwrap" because the best place I think to do this is directly after all the Expr's get desugared but before the rest of canonicalisation. Specifically, in crates/compiler/can/src/suffixed.rs, you will find the unwrap_suffixed_expression which is responsible for desugaring the ! operator. So we can modify this to also handle the ? suffix. You can find the tests for this in crates/compiler/can/tests/test_suffixed.rs

If you need any assistance with parsing @joshuawarner32 is definitely the expert. For more general things @kdziamura and myself have been working in this part of the compiler recently. Hope this helps. 😍

@sekerez
Copy link
Contributor

sekerez commented Jun 27, 2024

Thanks @lukewilliamboswell!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
can Canonicalization enhancement New feature or request intermediate issue Likely good for someone who has completed a few other issues parsing
Projects
None yet
Development

No branches or pull requests

3 participants