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

Pattern negation #7628

Open
vicuna opened this issue Sep 15, 2017 · 9 comments
Open

Pattern negation #7628

vicuna opened this issue Sep 15, 2017 · 9 comments

Comments

@vicuna
Copy link

vicuna commented Sep 15, 2017

Original bug ID: 7628
Reporter: @gasche
Status: acknowledged (set by @xavierleroy on 2017-09-29T18:17:36Z)
Resolution: open
Priority: low
Severity: feature
Category: language features
Monitored by: @stedolan @yallop @alainfrisch

Bug description

I would like to be able to write the pattern not p, where p does not contain variables, to match the values that do not match p.

Pattern negation is useful both in theory and in practice:

  • In theory, it gives a nice way to describe a decomposition of the value space of a pattern alternation in a way that is independent of pattern ordering/priority. For example, if you see a match with three clauses "| A -> ...", "| B -> ..." and "| _ -> ...", you know that the matched space is the disjoint sum of A, B, and not (A | B).

  • In practice, it gives a convenient way to write patterns in an order that improves readability by treating the exceptional cases first.

Consider this random example:

    let typ =
      match repr typ with
      | {desc = Tpoly (ty, [])} ->
          instance env ty
      | {desc = Tpoly (ty, tl); level = l} ->
          if !Clflags.principal && l <> generic_level then
            Location.prerr_warning loc
              (Warnings.Not_principal "this use of a polymorphic method");
          snd (instance_poly false tl ty)
      | {desc = Tvar _} as ty ->
          let ty' = newvar () in
          unify env (instance_def ty) (newty(Tpoly(ty',[])));
          (* if not !Clflags.nolabels then
             Location.prerr_warning loc (Warnings.Unknown_method met); *)
          ty'
      | _ ->
          assert false
    in

I think this would be more nicely written

    let typ =
      match repr typ with
      | {desc = not (Tpoly _ | Tvar _)} ->
        assert false
      | {desc = Tpoly (ty, [])} ->
          instance env ty
      | {desc = Tpoly (ty, tl); level = l} ->
          if !Clflags.principal && l <> generic_level then
            Location.prerr_warning loc
              (Warnings.Not_principal "this use of a polymorphic method");
          snd (instance_poly false tl ty)
      | {desc = Tvar _} as ty ->
          let ty' = newvar () in
          unify env (instance_def ty) (newty(Tpoly(ty',[])));
          (* if not !Clflags.nolabels then
             Location.prerr_warning loc (Warnings.Unknown_method met); *)
          ty'
    in

Additional information

In many cases not [] would be more readable/informative than _ :: _.

@vicuna
Copy link
Author

vicuna commented Sep 15, 2017

Comment author: @xclerc

This is a nice idea, immediately translated to ppx_view, see:

https://github.com/ocaml-ppx/ppx_view/blob/not-pattern/example/ex05_not.ml

@vicuna
Copy link
Author

vicuna commented Sep 29, 2017

Comment author: @xavierleroy

Mr. Pattern Matching here sounds grumpy about this proposal, but I'll leave it open in the interest of a fair debate.

@github-actions
Copy link

github-actions bot commented May 7, 2020

This issue has been open one year with no activity. Consequently, it is being marked with the "stale" label. What this means is that the issue will be automatically closed in 30 days unless more comments are added or the "stale" label is removed. Comments that provide new information on the issue are especially welcome: is it still reproducible? did it appear in other contexts? how critical is it? etc.

@github-actions github-actions bot added the Stale label May 7, 2020
@gasche
Copy link
Member

gasche commented May 9, 2020

I still believe that this feature would be important to have: since I have understood that it should exist, I keep finding cases where it would lead to more readable code (often by moving short error cases first in a matching, before long/important clauses).

For me the priority is to refactor the existing pattern-matching compiler and make it more robust, not implement new features, but I think that this one has value and would like to keep track of it.

I don't understand what is the new unspoken policy on opening/closing feature wishes, but for me this should stay open, because it is a valid feature wish.

@gasche gasche removed the Stale label May 9, 2020
@github-actions
Copy link

This issue has been open one year with no activity. Consequently, it is being marked with the "stale" label. What this means is that the issue will be automatically closed in 30 days unless more comments are added or the "stale" label is removed. Comments that provide new information on the issue are especially welcome: is it still reproducible? did it appear in other contexts? how critical is it? etc.

@github-actions github-actions bot added the Stale label May 12, 2021
@gasche gasche removed the Stale label May 12, 2021
@gasche
Copy link
Member

gasche commented May 12, 2021

Still interested in this feature. (cc @Octachron who was wondering which exciting pattern-matching feature could be considered in the post-refactoring state.)

@github-actions
Copy link

This issue has been open one year with no activity. Consequently, it is being marked with the "stale" label. What this means is that the issue will be automatically closed in 30 days unless more comments are added or the "stale" label is removed. Comments that provide new information on the issue are especially welcome: is it still reproducible? did it appear in other contexts? how critical is it? etc.

@github-actions github-actions bot added the Stale label May 16, 2022
@Octachron
Copy link
Member

I am still potentially interested in implementing the feature.

@github-actions github-actions bot removed the Stale label May 18, 2022
@github-actions
Copy link

This issue has been open one year with no activity. Consequently, it is being marked with the "stale" label. What this means is that the issue will be automatically closed in 30 days unless more comments are added or the "stale" label is removed. Comments that provide new information on the issue are especially welcome: is it still reproducible? did it appear in other contexts? how critical is it? etc.

@github-actions github-actions bot added the Stale label May 22, 2023
@Octachron Octachron removed the Stale label May 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants