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

[WIP] pattern-matching: Cannot_flatten, maybe we can? #9650

Merged
merged 12 commits into from Oct 21, 2020

Conversation

gasche
Copy link
Member

@gasche gasche commented Jun 7, 2020

This PR implements a new approach to "flattening" pattern-matching compilation (do_for_multiple_match) for source programs of the form match foo, bar, baz with .... (The pattern-matching compiler is trying to avoid allocating a tuple if possible, that is if the patterns do not use the name of the tuple. The point of this PR is to change the details of how this is implemented.)

The goal of getting rid of the Cannot_flatten exception is to simplify reasoning on the codebase. It looks like we actually produce better code, but this was not the intent -- the examples where we see a different are relatively artificial and may not exist in real codebases.

This PR is only a Work-in-Progress, because the "simplify the reasoning" part is only half-achieved. We do not have Cannot_flatten anymore, so the control flow is simpler, but the correctness reasoning for the flatten_* functions has become more subtle: whereas we knew before that they would never encounter (and throw away) as-patterns, they can now reach as-patterns, but only in usage modes (default environments, provenance) where (I believe that) variables do not matter anyway, so ignoring them is fine.

(cc @maranget, @trefis, @Octachron)

@gasche
Copy link
Member Author

gasche commented Jul 6, 2020

We had a meeting today about this PR with @trefis and @maranget. @maranget is willing to get rid of exceptional control-flow, if the code really is simpler. @trefis or @Octachron proposed to review the PR (eventually) to get a third-party opinion (or two) on whether the change actually simplifies the code.

@gasche gasche marked this pull request as ready for review July 6, 2020 08:56
lambda/matching.ml Outdated Show resolved Hide resolved
Copy link
Contributor

@trefis trefis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some meta-comments about the tests.
I'll look more carefully at the code later.

testsuite/tests/basic/patmatch_for_multiple.ml Outdated Show resolved Hide resolved
testsuite/tests/basic/patmatch_for_multiple.ml Outdated Show resolved Hide resolved
testsuite/tests/basic/patmatch_for_multiple.ml Outdated Show resolved Hide resolved
@gasche
Copy link
Member Author

gasche commented Jul 7, 2020

I did the changes suggested by @trefis. To make the -drawlambda output less noisy I added some logic to avoid identifier-rebinding in do_for_multiple_match.

@gasche gasche force-pushed the matching-can-flatten branch 3 times, most recently from f2e274a to 08d3b4b Compare July 7, 2020 17:07
Copy link
Contributor

@trefis trefis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some further nitpicking, but otherwise the code looks correct to me.

lambda/matching.ml Outdated Show resolved Hide resolved
compile a tuple pattern [match e1, .. en with ...]
without allocating the tuple [(e1, .., en)].
*)
let env = List.map (fun id -> id, Ident.rename id) vars in
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not all of the fresh new ids are being used, so you could delay the call to Ident.rename until you know that you're going to be using the id.
Also, I think the code would be easier to read without one more env variable with a different meaning from other envs in this file. (I know the name was there before your PR, but let's take the opportunity to change it!)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm trying to apply your on-demand-rename suggestion:

  • bad news: the resulting code is even more complex than the current one
  • good news: this forced me to write a comment to explain what the function does in the first place, and I realized that we can probably simplify its interface a bit (it does not need to take the patl as part of the input as it ignores them, and in particular does not freshen any variables they would bind in the action, which is fine as the function is only called with omega-patterns there!).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pushed commits corresponding to those changes, let me know what you think.

@trefis
Copy link
Contributor

trefis commented Jul 8, 2020

PS: What about the changes entry?

@gasche gasche force-pushed the matching-can-flatten branch 3 times, most recently from 7814416 to 045d106 Compare July 10, 2020 08:37
@gasche
Copy link
Member Author

gasche commented Jul 11, 2020

@trefis I believe that I have addressed your comments (although for fresh-id generation you might think that the cure is worse than the disease, with the resulting code more complex; let me know and I can always revert), and now the CI is green. Hint hint.

@gasche
Copy link
Member Author

gasche commented Oct 20, 2020

(recently I wondered about which of the pattern-matching PR are still in-flight; this one is)

Copy link
Contributor

@trefis trefis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the long delay, I'm satisfied with current state of things.

I did voice one nitpick, which hopefully you won't mind addressing since you need to rebase anyway to handle the conflict in Changes.

lambda/matching.ml Outdated Show resolved Hide resolved
Note: we now use -dlambda rather than -drawlambda, because otherwise
the output is much more verbose and difficult to read.

(-drawlambda is closed to the inner workings of the pattern-matching
compiler, but the simplification in -dlambda make the output much more
readable. They are also fairly predictable/non-surprising, so I think
that we can still easily understand what the compiler did from that
output.)
Changes Outdated Show resolved Hide resolved
…bles

Before we ignored as-patterns in the flatten_* functions because
as-patterns would either be half-simplified or raise Cannot_flatten
(in any case, never reach the flattening functions).

Now the reasoning is a bit more subtle: the only non-simple matrices
we flatten are used as "ghost" information (default environments,
provenance) where variables do not matter, only the shape of matched values.
…iers

This change was suggested by Thomas Refis during code review.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants