
#8185: Change role annotation syntax ----------------------------+---------------------------------------------- Reporter: | Owner: goldfire goldfire | Status: new Type: feature | Milestone: 7.8.1 request | Version: 7.7 Priority: normal | Keywords: Component: | Architecture: Unknown/Multiple Compiler | Difficulty: Moderate (less than a day) Resolution: | Blocked By: Operating System: | Related Tickets: Unknown/Multiple | Type of failure: | None/Unknown | Test Case: | Blocking: | ----------------------------+---------------------------------------------- Comment (by goldfire): In a late afternoon conversation, Stephanie and I seemed to make some progress here. Of the three main alternatives I presented a few days ago, we agreed that the first was best, but with `type role` instead of `type roles`, to be consistent with the wealth of other, singular keywords. Why? * It makes the most sense with the different declaration forms that it affects. In particular, anything involving a `where` clause is awkward with non-GADT datatype declarations. We also toyed around with using a `deriving` clause, but that's awkward in general and in particular with classes. We even considered a `roles` clause that would syntactically be like `deriving`, but that would have to make `roles` a keyword. * Stephanie was very against my idea of including the role within the kind, because a role is really quite separate from a kind. The "include with kind" idea also makes using CPP for compatibility control rather painful. * Having separate role declarations makes dealing with backward compatibility more palatable, as a library author can lump all of a module's role declarations in one place, cordon the place off with an `#if`, and move on. Not quite as seamless as a pragma, but not so bad, either. * As Iavor pointed out in an email to me, having a separate declaration allows roles to be declared for promoted types. It's not clear to me what the value of this is, exactly, but it certainly won't hurt anyone. Knowing this community, someone will find a use for this feature. So, concretely, I propose the following form: A role declaration looks like {{{ type role <typename> <roles> }}} where `<typename>` is the name of the type being decorated (operators put in parentheses as usual). `<roles>` will be spelled out and in lowercase: {{{ type role Map nominal representational }}} The first word of the line will always be `type`, regardless of whether the actual declaration is a `data` or a `class`. (Separately (#8234), it has been decided to retract role annotations on type synonyms as too fragile.) If a role is to be inferred, it can be left out with `_`: {{{ type role Map' nominal _ }}} The number of roles given in a declaration must exactly match the number of (type, not kind) parameters in the real type declaration, including unnamed parameters in a GADT-style declaration. Role declarations are allowed for `data` and `class` types, and for promoted types, but not for families or other type-level declarations. How does this sound? Once implementation is under way, I'll add this proposal to [wiki:Roles] on the wiki. And, of course, I'll add notes in the user manual. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8185#comment:11 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler