Skip to content

RFC: Allow matching against n-ary variants with just the name #1701

Description

@marijnh

There's lot of stuff like this in the current code:

alt expr.node {
    expr_field(_, _) | expr_index(_, _) { ... }
}

Where we need to have the (_, _, _) in there even though we just want to match a variant, and don't care about the arguments. If I understand correctly, we're already disallowing shadowing such variants in patterns, so it is probably a good idea to also allow matching against them with just their name. I.e.

alt expr.node {
    expr_field | expr_index { ... }
}

Activity

  1. catamorphism commented on Jan 29, 2012

    @catamorphism
    Contributor

    Haskell does something like Foo{} to mean "match on Foo and I don't care how many arguments it has". The exact syntax doesn't matter, but it seems like distinguishing that case from the case where Foo is nullary might make the implementation a little simpler.

  2. marijnh commented on Jan 29, 2012

    @marijnh
    ContributorAuthor

    The implementation is already trivial even without extra syntax -- in fact, I think it'd mostly be a matter of removing the check that currently causes the error.

  3. brson commented on Jan 30, 2012

    @brson
    Contributor

    I like the idea of making this case easier, but I think using the same syntax as nullary variants could make refactoring very difficult in one situation. Right now every time you change a tag you can lean on the compiler to tell you everything you need to update. Giving both these scenarios the same syntax will mean the compiler can't distinguish between the 'I believe this is a nullary variant' and 'I don't care how many arguments this variant has' cases. So promoting a variant from 0 arguments to some arguments gets you no feedback from the compiler.

  4. marijnh commented on Jan 30, 2012

    @marijnh
    ContributorAuthor

    But what is the situation where this might actually introduce a bug? If you
    add a new arg to a variant, presumably existing code matching it doesn't
    need this value. There are cases where it does, but you can't protect the
    user from all refactoring problems (they could also change arg order,
    rename something, etc, which is easily more dangerous).

  5. catamorphism commented on Jan 30, 2012

    @catamorphism
    Contributor

    What if you change a variant from nullary to unary? It's possible that code might have to treat values constructed with that constructor differently depending on the value of the field.

    It's true that we can't protect the user from all refactoring hazards, but to me that doesn't seem like a very good argument for disregarding any particular hazard. Obviously, there are some we'll address and some we won't, but the fact that there'll be some that we won't doesn't provide any help in choosing which ones to address.

  6. marijnh commented on Jan 30, 2012

    @marijnh
    ContributorAuthor

    A) Extra syntax is also a cost.

    B) The idea to distinguish nullary from n-ary doesn't even solve the (theoretical) problem. You'd still have the same issue adding an argument to a tag that already had arguments—the existing cases that match 'this variant with any arguments' would keep on matching.

    But that is exactly the point of this proposal. To reduce needless coupling. If coupling is something you guys consider a good thing, then we're just arguing from completely different standpoints.

  7. pcwalton commented on Feb 2, 2012

    @pcwalton
    Contributor

    I'd tend to agree with Tim — sometimes coupling is good because it helps refactoring, and sometimes it's a nuisance. Depends on the situation, I think.

    I like the idea of having a pattern (maybe foo _, distinct from foo(_) or foo), that means "just match against foo, I don't care how many arguments it has—or even if it's nullary or n-ary".

  8. marijnh commented on Feb 3, 2012

    @marijnh
    ContributorAuthor

    How about name* (rather than name _)? I like the way it looks slightly more.

  9. nikomatsakis commented on Feb 10, 2012

    @nikomatsakis
    Contributor

    I think this would be great. I was going to propose the syntax name(*) or name(_*) but I see there are many other proposals... I don't really care but I think @marijnh is right that we need something like this. It's very annoying to refactor otherwise.

  10. graydon commented on Feb 15, 2012

    @graydon
    Contributor

    foo(...) perhaps?

  11. nikomatsakis commented on Feb 15, 2012

    @nikomatsakis
    Contributor

    I personally like foo(...).

  12. marijnh commented on Feb 16, 2012

    @marijnh
    ContributorAuthor

    It is my understanding that ... is already claimed by the macro system, in pretty much every syntactic context.

  13. catamorphism commented on Apr 12, 2012

    @catamorphism
    Contributor

    It seems like there is consensus that we should implement this, and it's just down to choosing the syntax. I volunteer to do it -- I favor name(*) as suggested by @nikomatsakis but if you object, comment soon.

  14. catamorphism commented on Apr 20, 2012

    @catamorphism
    Contributor

    I've implemented the new syntax, but going through and using it is still a separate task (probably easiest to do it incrementally, or I suppose someone could do an automated search-and-replace).

  15. added a commit that references this issue on Mar 21, 2021
  16. added 2 commits that reference this issue on Aug 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-frontendArea: Compiler frontend (errors, parsing and HIR)E-easyCall for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions