-
-
Notifications
You must be signed in to change notification settings - Fork 313
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
Parser simplification and Closure Shortcut features #7212
Conversation
This reverts commit ea23576.
… for underscore ident
This has a lot of pretty impactful changes to the language that haven't been through any discussion or feedback from the community. It looks like some fun stuff to experiment with, but you shouldn't expect these sorts of changes to be merged into the language without getting general consensus on them first. |
I think there are some promising ideas and improvements here, however as @skyqrose has mentioned these changes have not been discussed with the community and they will have a significant impact on the language. These kinds of changes to the core language are typically discussed in great length under the guidance of @rtfeldman. I recommend you checkout our (informal) process for managing PRs here. As @bhansconnect mentioned in zulip, you should consider splitting this up into separate proposals. I can imagine some of the improvements and simplifications would be most appreciated. I am closing this PR as it will not be accepted in this form. Again, thank you for sharing this and I hope we can land some of these improvements. |
@lukewilliamboswell will you be interested if I split the PR into performance improvements and simplification of the parser, and keep the features aside? |
Simplify Parser and add closure shortcut features
Initial intent
I wanted to add a fun feature, a syntax sugar for the closure of single argument with pipe,
where this code
\|> foo
translates to\x -> x |> foo
.To identify the place where I can add the feature, I have started from the parser.
My debugging experience with Roc parser was miserable. TL;DR; too many nested calls, closures, and macros.
So I've started to unwind the Parser from the original
closure_help
function and ended up with this PR :-)Goals
Done
\ -
\.foo
,\.foo.bar
or\.0.buzz
. Note: consider how this functionality adds-up to the current RecordAccessor.foo { foo: 3 }
and RecordUpdater&foo { foo: 1 } 42
functions.i -> i
, via\.
x ~ ...
binary operator for the pattern matchingwhen x is ...
when
pattern matching using the~
operator via\~
\-.
and\!.
This syntax should be composable with the record/tuple field access, e.g.\!.foo.bar
,\-.a + y.b
, etc.Further
Random
todo: @perf
cargo test --release
takes 5 min on my laptop, or e.g.time cargo test -p roc_load --test test_reporting
takes 20s. Whaterver it does, it is a lot.PR does not
It is not a serious optimization of the parser.
I was refactoring and moving existing parts around, removing what become redundant in the process.
Mmm, OK. I did a small optimization/non-pessimization (TM) using the opportunities emerging from the inlining and replacing the combinators with the direct function calls. For example,
parse_term
checks the first character before calling the appropriate parsing function for the rest of the input.PR does
EClosure::Comma
,EWhen::Bar
,EWhen::IfToken
, and many more.spaced_before
,spaced_around
abstracting the repetition of the same code in many places.Parser Benchmarks
cd ./crates/compiler/parse && cargo bench
main branch:
PR branch:
New debug experience
Comparing the call-stacks when debugging the test from the test_syntax:
Breakpoint is on the construction of the AST node for the
WhenBranch
.In the main branch (barely fitting on my laptop screen with the smallish font):
In this PR branch:
Features
Closure shortcut for the binary and unary operators, record field and tuple accessors, identity function
It is working for all binary and unary operators, including the Pizza pipe operator
|>
and the new~
operator for the pattern matching, the record field, tuple accessors and the identity function.Plus, those shortcuts are naturally combining, e.g. unary negate with identity and access, then further with the binary operator chain.
Tests for illustration:
Current implementation changes the Parser to create the same AST for shortcut
\|> bar
as for the normal\x -> x |> bar
.I am still saving the information that the closure is in fact a shortcut via the additional field in
Expr::Closure
.When the flag is set, the Roc format is adjusted to output the AST in the short form
User-guided shortcut expansion
By inserting the whitespace after
\
in the closure shortcut, the User indicates the expansion into the full form on theroc format
:Say you've typed
\|>
shortcut, then you can put space between opening\
and|>
in\ |> foo
and it will expand into\x -> x |> foo
on format (automatically with format-on-save and auto-save enabled in the editor).Example:
Binary operator for the when pattern matching
Implemented as
~
symbol, which is not yet used by the other features.The difference from the
|>
is that it should be the last in the chain of the binary operators.