Conversation
It's useless to do so, but I don't see why this would be problematic. Do you see such a reason? |
|
No, as far as I can see, bringing values to the scope should not create any problem. It just feels non optimal to add values in the environment which are never used. |
|
For the issue of performance of local opens, see also http://caml.inria.fr/mantis/view.php?id=6826. |
|
I'm not familiar with the type-checking of patterns, and in particular about why an "Env.t ref" is passed (and not an Env.t) in type_pat. The new case for Tpat_open loose sharing these references. Does it matter? |
|
It does matter. In presence of gadt constructor, the Thanks for pointing this stupid mistake, I will correct it soon. |
|
I updated the pull request to fix the problem when mixing gadt and pattern open. The new commit fix this problem by controlling more finely which information is shared between environment during pattern typing:
To solve these constraints, I have added an environment stack in type_pat. When entering a pattern open, the signature of the associated module is added to a copy of the current environment. This new env is then pushed on the environment stack and poped when exiting the pattern open. Environment changes during pattern typing are then propagated to the whole stack. A major caveat of this approach is that type equalities are recomputed at each level of the stack. Fortunately, it should mainly affect patterns with gadt constructors deeply nested inside pattern open. It seems sensible to conjecture, for now, that these patterns will be uncommon. If this cause performance problems in the future, it should be possible to optimise this behavior. However, I think that this optimisation would probably need more invasive changes, whereas the current code does not alter pattern typing in absence of pattern open.
|
|
Jacques Garrigue is working on a branch ( http://caml.inria.fr/cgi-bin/viewvc.cgi/ocaml/branches/gadt-warnings/ ) with a much revised version of pattern type-checking (for better support of GADTs). It would be useful to synchronize with him on this topic. I'm not so fond of the stack approach. It seems the environment is used for two different purposes (collecting equalities, resolving lookups); isn't there a way to separate these uses and keep only two environments, one for each use? |
|
The stack solution is clearly hackish. A better long-term solution might be to split the environment between a shared part and an immutable part during type unification. Splitting the environment might also slightly facilitate the environment backtracking in the gadt-warning branch. I would have a look at this idea this week. |
|
I have added a new version which does not use an environment stack when typing a local open in pattern. To achieve this goal, I have added an I have also added an |
|
(For the record, I asked Jacques for an opinion on the patch, but he needs more time for a review.) |
524e590 to
b9d8340
Compare
|
Since the gadt-warning branch have been merged back to trunk, I have rebased this pull request to solve the resulting merge conflicts. Most of the changes were quite trivial. The only exception might be the function After some hesitations, I have also added the syntactic sugar for |
parsing/parser.mly
Outdated
There was a problem hiding this comment.
Out of curiosity: what does arl stand for?
There was a problem hiding this comment.
It stood for array_record_list. A better name might be simple_delimited_pattern or maybe simply
simple_pattern_array_record_list.
a913f31 to
31c8d4f
Compare
|
@garrigue do you have time to review this patch? @Octachron Could you add an entry in |
49e983b to
f0fb748
Compare
|
I have added a change entry in I have also cleaned a little bit the code: comments have been somewhat improved and the french-influenced Were the pull request accepted, I would clean the history to clear up the wandering between implementations. (side-note: parallel builds of world.opt have been broken once again due to a desynchronized |
|
Sorry, I won't have time for this until next week. |
During type unification and pattern typing in presence of GADTs, it is useful to be able to share type equalities. Before this commit, this was done by using a environment reference to modify the environment when needed. However, that made impossible to locally update the environment without either losing the shared reference or propagating globally the changes. This is problematic for local opens in pattern that need to introduce new identifiers in the environment for the sake or name lookup but only within a limited scope. This commit introduces an `Env.mut` type to fix this limitation in preparation of local open in pattern.
This commits extends the pattern syntax to support local open in
patterns. Four new constructions mirroring the expression constructions
are added
* `M.(pattern)`
* `M.[pattern_list]` ⟺ M.([pattern_list])
* `M.{labeled_pattern_list}` ⟺ M.({label_pattern_list})
* `M.[| .. |] ⟺ M.( [| .. |] )
At the typing phase, the construction `M.(pattern)` brings all
identifiers defined within M inside the scope and then proceed with the
typing of `pattern`. All others constructions are desugared to the
`M.(..)` construction during parsing.
Questionable implementation details:
* Currently, the local pattern open use the `type_open` function like
the local expression pattern. However, this implies that values defined
inside `M` are also brought to the scope. A specialized
`type_open_for_pattern` would be more efficient.
|
Some minor changes: I have cleaned the PR history and rebased onto trunk. I have also simplified a little the code by removing the environment id change. |
|
After reading the code, I have no problem with the basic idea, but the freeze/thaw seems an overkill. |
|
I have opened a new pull request #578 for my branch of this patch. |
|
Thanks for the review and the code change. Threading just the local type information looks indeed much better. I am closing this PR in favor of #578. |
|
I rebased the two patchsets together and merged in trunk ( 2d33e16 ). Thanks for the work! |
This pull request adds support for local open inside patterns. Four new constructions mirroring the local open constructions for expressions are added
M.(pattern)M.[pattern_list]⟺M.([pattern_list])M.{labeled_pattern_list}⟺M.({labeled_pattern_list})M.[| .. |]⟺M.( [| .. |] )At the typing phase, the construction
M.(pattern)brings all identifiers defined within M inside the scope and then proceed with the typing ofpattern. All others expression are desugared to theM.(..)construction during parsing.One the main advantages of these constructions would be to deconstruct record with the same
syntax used to construct them
Other uses of these local pattern might be quite unfrequent but the similarity with the local open for expression should help users to discover or remember this feature when the need arises. Since there is no analogous to
let open M in ...on the pattern side, local open in pattern and expression are not completely symmetric. However,let open M in ..constructions in the pattern side would look quite foreign to me.Questionable implementation details:
type_openfunction like the local expression pattern. However, this implies that values defined insideMare also brought to the scope. Does this warrant a specialisedtype_open_for_patternfunction?M.()andM.[]whose semantics seem quite ambiguous to me.