-
Notifications
You must be signed in to change notification settings - Fork 90
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
Full pattern matching #1820
Full pattern matching #1820
Conversation
7b15269
to
b9eb971
Compare
// if final_bindings_id == null then | ||
// null | ||
// else |
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 interesting part of this change is here: it was missing a null check which could lead at runtime to %record_remove%
complaining that its argument is null on valid (albeit unmatching) patterns. The rest of the diff in this file is just the implementation of this change.
2a9448e
to
5d2c776
Compare
🎉 All dependencies have been resolved ! |
This commit brings together many previous chunks of work to finally make match expressions accept generic patterns, and not just enum tags. Pattern compilation was already implemented. Besides changing the parsing rule for "match" and change the implementation to compile the pattern and applies the result to the argument, the bulk of the work has been to correctly typecheck arbitrary structural patterns. Refer to the comments for the "Match" case in the typechecker for more details about the algorithm.
The compilation of record pattern was missing a null check which would trigger a dynamic type error when some matches aren't exhaustive. This commit fixes the issue by adding the missing null check.
3f049a0
to
ffbf185
Compare
Co-authored-by: Viktor Kleen <viktor.kleen@tweag.io>
Depends on #1819.
This PR finally brings the work done around patterns and ADTs together by making match expressions accept arbitrary patterns on the left hand side of the
=>
sign. This results in both full pattern matching, and the ability to deconstruct ADTs in a type-safe way.Beside some administrative changes (changing the parsing rule of
match
, switching to the pattern compilation instead of the current ad-hoc evaluation of match expressions for enum tags, etc.), the bulk of the new work of this PR is the typechecking of general patterns.Typechecking
For simplicity, I reproduce here what I wrote as a comment inside the typechecker:
In consequence, the current approach to typecheck a pattern is:
typecheck::pattern
, thepattern_types
function which elaborates the type of a pattern as well as its variables always elaborates open-ended enum rows when it encounters an enum pattern. It saves the open tail in a vector, together with a pattern path, which localizes the enum pattern inside the wider patternmatch { 'Foo => .., 'Bar => .., _ => } : forall rows. [| 'Foo, 'Bar; rows |]
. The other paths are currently not leveraged, but we can imagine in the near future having wildcard patterns, in which case we would also let open the tails corresponding to each path where there is a wildcard pattern: typically, we would havematch { {foo = 'Foo} => ..., {foo = 'Bar} => ..., {foo = _} => ...} : forall rows . { foo : [| 'Foo, 'Bar; rows |] }
Content
Besides the typechecking implementation, the rest is mostly obvious consequences of generalizing match expressions, as well as bug fixing in pattern compilations and pattern type checking discovered by adding more comprehensive tests.
Follow-up (ADTs + patterns)
'Foo
to be matched by'Foo x
or not, adding%unit%: %Unit%
.