-
Notifications
You must be signed in to change notification settings - Fork 277
Lambda-case cases
syntax
#1192
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
Lambda-case cases
syntax
#1192
Conversation
@anovstrup Discussion on Slack is for more general lambda case mechanism. Dan suggesed
I like this proposal. You need some keyword or token to introduce such a lambda. Should the keyword be I think it has to be syntactically distinct from the keyword that introduces a regular pattern matching, otherwise ambiguity. |
d59134f
to
afca605
Compare
@pchiusano Can you recommend someone to review this PR? I'm not sure who's best able to review parser/lexer/pretty-printer changes. It's not ready to merge, yet, but I'd appreciate feedback before going further, when somebody's got time. |
@anovstrup - could we actually do I read the I'll take a look at the lexer / parser changes. @atacratic could you review the pretty-printer changes? |
@anovstrup honestly, seeing some of the complexity in the lexer makes me wonder if we should punt on the Like just do the lambda case WDYT? |
@pchiusano 😬 You're killing me! :) Although the lexer changes did end up being more of a bear than desirable, they're already done. If review is too difficult, my preference would be to add code/review comments rather than throw the changes away. That said, I could cherry-pick the |
@anovstrup lol, okay, sorry! I misinterpreted your "It's not ready to merge, yet, but I'd appreciate feedback before going further, when somebody's got time." thinking you still had stuff that needed working out. If you were doing this from scratch it would have been better to separate the lambda cases into a separate PR but I think it's okay not to split them up now and I'm guessing it'd be a hassle. I'll review the parser and lexer changes, hopefully this weekend sometime. |
@pchiusano Splitting off a PR would be easy, actually. The commits for lambda-case are separate from ones for match-with, so it's a simple cherry-pick. There's still stuff to do (for both parts; see the checkboxes in the description), but the hardest stuff is done (I think). |
1b1a2fc
to
46c312b
Compare
@pchiusano @atacratic I split off the |
88d23fb
to
894f2fb
Compare
@anovstrup for the pretty-printer, I think you could check here inside LamsNamedOrDelay' vs body ->
let (im', uses) = calcImports im body'
-- In the case where we're being called from inside `pretty0`, this
-- call to printAnnotate is unfortunately repeating work we've already
-- done.
body' = printAnnotate env body
in PP.group
$ PP.group (defnLhs v vs <> fmt S.BindingEquals " =")
`PP.hang` uses [pretty0 env (ac (-1) Block im' doc) body'] You can use the Let me know how it goes! |
@pchiusano Thanks for the tip. I've starting looking at it -- hopefully I'll have something working this weekend. |
@pchiusano Turns out it's a bit more complicated, I think. In the cases we're interested in, I'll also need to handle |
@anovstrup - cool, yeah that makes sense. You don’t need to do anything for the patterns, those don’t contain variable references, just the RHS and guards is sufficient. You can take my word for this for now, but I’ll dig up link re: how pattern matching is encoded with ABTs if you are curious. |
@pchiusano Progress! I'm probably not dealing with imports correctly, though — I'd appreciate if you or @atacratic could review my WIP when you get a chance. In the meantime, I'm going to work on adding more test cases and pretty-printing |
Any idea why this would fail as a test case in the TermParser tests, while a similar form parses and typechecks just fine in ucm?
It fails with:
This, on the other hand, parses, typechecks, and evaluates correctly in ucm:
|
I made the Abort example a test case, and it fails with this:
So I guess that explains the other failure... I didn't realize that the parser knew about existing definitions/names. |
@anovstrup yes pattern constructor references are resolved at parse time. This was a mistake but isn’t a slam dunk to fix. |
…or `cases` parsing / pretty-printing
This is ready for review, but I'm not that confident about the pretty-printing code. |
Sorry for not taking a look at this yet - I'll review the pretty-printer changes on Wednesday night. Great that you've done this! 👍 |
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.
TermPrinter changes look good!
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.
Looks great @anovstrup am stoked to try this out!!
It is pretty cool how easy it is to make changes to the syntax, and how existing code will render using cases
when possible, just via that tweak to the pretty printer.
Just (reverse -> (v1:vs), Match' (Var' v1') branches) | | ||
(v1 == v1') && not (Set.member v1' (Set.unions $ freeVars <$> branches)) -> | ||
Just (reverse vs, branches) |
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.
These three lines are pretty epic and are doing a lot, but pretty easy to follow.
I might have written as not (any (Set.member v1') (freeVars <$> branches))
to avoid needing to build up the union'd Set
(which does a bunch of tree rebalancing stuff) but I think it's totally fine as is.
This PR provides support for syntax like the following:
Changes:
cases
keyword)Before the next release: