-
Notifications
You must be signed in to change notification settings - Fork 471
PoC of let? #7582
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
base: master
Are you sure you want to change the base?
PoC of let? #7582
Conversation
rescript
@rescript/darwin-arm64
@rescript/darwin-x64
@rescript/linux-arm64
@rescript/linux-x64
@rescript/win32-x64
commit: |
Looks like a great feature in development! BTW some languages place ? around the = like ?= or =?. I wonder if this has been considered. This can potentially also be used with if. |
@leoliu thank you! There's now a forum post for the proposal where you can add your thoughts if you want: https://forum.rescript-lang.org/t/proposing-new-syntax-for-zero-cost-unwrapping-options-results/6227 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR implements the "let?" syntax (LetUnwrap) as an experimental feature for ReScript, providing syntactic sugar for early-return patterns with Result and Option types. The implementation hides this functionality behind an experimental feature flag that must be explicitly enabled.
Key changes:
- Adds the
let?
syntax that automatically unwraps Result/Option types with early return behavior - Implements experimental feature infrastructure with configuration support in rescript.json
- Provides comprehensive error handling and validation for the new syntax
Reviewed Changes
Copilot reviewed 40 out of 40 changed files in this pull request and generated 3 comments.
Show a summary per file
File | Description |
---|---|
tests/tests/src/LetUnwrap.res |
Test cases demonstrating let? syntax with Result, Option, and async patterns |
tests/tests/src/LetUnwrap.mjs |
Generated JavaScript output showing the transformation logic |
tests/syntax_tests/res_test.ml |
Parser test update for new Let token structure |
tests/syntax_tests/data/printer/expr/letUnwrap.res |
Printer test cases for let? syntax |
tests/syntax_tests/data/parsing/grammar/expressions/letUnwrap.res |
Grammar parsing test cases |
tests/syntax_tests/data/parsing/errors/signature/letUnwrap.resi |
Error test for let? in signatures |
tests/syntax_tests/data/parsing/errors/expressions/letUnwrapRec.res |
Error test for let? with rec |
tests/build_tests/super_errors/fixtures/* |
Error handling test fixtures |
rewatch/src/config.rs |
Configuration support for experimental features in rescript.json |
rewatch/src/build/compile.rs |
Compiler argument generation for experimental features |
compiler/syntax/src/res_token.ml |
Token definition updates to support let? |
compiler/syntax/src/res_scanner.ml |
Scanner updates to recognize let? syntax |
compiler/syntax/src/res_printer.ml |
Pretty printer support for let? |
compiler/syntax/src/res_grammar.ml |
Grammar updates for let? parsing |
compiler/syntax/src/res_core.ml |
Core parsing logic for let? with validation |
compiler/ml/experimental_features.ml |
Experimental feature management system |
compiler/frontend/bs_syntaxerr.ml |
Error message definitions for let? |
compiler/frontend/bs_builtin_ppx.ml |
AST transformation logic for let? to switch expressions |
compiler/frontend/ast_attributes.ml |
Attribute handling for let.unwrap marker |
compiler/bsc/rescript_compiler_main.ml |
Command line flag support for experimental features |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
let enable_from_string (s : string) = | ||
match from_string s with | ||
| Some f -> enabled_features := FeatureSet.add f !enabled_features | ||
| None -> () |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The enable_from_string
function silently ignores unknown feature names. This could lead to configuration errors being missed. Consider logging a warning or returning a result type to indicate failure.
let enable_from_string (s : string) = | |
match from_string s with | |
| Some f -> enabled_features := FeatureSet.add f !enabled_features | |
| None -> () | |
let enable_from_string (s : string) : bool = | |
match from_string s with | |
| Some f -> | |
enabled_features := FeatureSet.add f !enabled_features; | |
true | |
| None -> | |
Printf.eprintf "Warning: Unknown feature name '%s' (ignored)\n" s; | |
false |
Copilot uses AI. Check for mistakes.
Co-authored-by: Copilot <[email protected]>
@@ -0,0 +1,11 @@ | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another super error test that I think we could have is for the case where let?
is used in a function whose return type is not result
/option
:
@@config({flags: ["-enable-experimental", "LetUnwrap"]})
let fn = (): int => {
let? Some(x) = None
42
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch! I added one: 47b70bb
...and the error is terrible. I gave it a quick shot to improve it:
5f196a0
@mediremi can you think of a good error message here?
EDIT: This is the current error:
We've found a bug for you!
tst.res:6:8-14
4 │
5 │ let fn = (): int => {
6 │ let? Some(x) = x
7 │ Some(x)
8 │ }
This has type: option<'a>
But this let? is used in a context expecting the type: int
let? can only be used in a context that expects option or result.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new error is a nice improvement to the original error message mentioning a switch 💪
Would it be possible to detect if the context is a function? That way we can have a clearer error message for that case where we say something along the lines of let? can only be used in a function that returns option or result
- since context that expects
may be confusing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried this out in a bsb project with "bsc-flags": ["-enable-experimental", "LetUnwrap"]
and it all works perfectly 🎉
Great work @zth 😁
@mediremi would you have another look at all the error messages now? |
The new error messages for |
Please feel free to add any other feedback in the coming days. We'll merge this under the experimental flag before the next beta release if nothing more comes up. |
EDIT: This is now hidden behind a new concept of "experimental features". Therefore, this is ready to be reviewed and merged as experimental, if we want to,
TODO