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
Extension lifecycle framework proposal (under review) #601
base: master
Are you sure you want to change the base?
Extension lifecycle framework proposal (under review) #601
Conversation
The link from the rendered proposal to this thread is broken. Broadly, looks sensible to me. |
I've fixed the broken link - thanks for the heads up! |
This looks very good to me. We've been working on some similar stuff over in Nix land for the same reasons. I don't want to derail this thread, but are the issue(s) with |
|
Thanks for writing this up. A few questions: @aspiwack is in the process of clarifying the purposes of Extensions, e.g. via multiple polls among the committee. It’s not quite the same question, but there is overlap. The two efforts should probably be synchronized to a point. I agree about the usefulness of I’m less sure about It seems to me that spelling out But I see your point: If the opt-in looks the same for experimental and mature extensions, there is nothing forcing the programmer to be aware of the experimental/mature distinction (which, it seems, you think worthwhile). But then maybe the problem isn’t with the experimental extensions (they require an explicit and loud opt-in), but with the mature extensions. If One conclusion could be that we don't need Of course, reality isn’t nice enough for that; there are features that are language extensions right now that are mature (in the sense of the current proposal), but for various reasons not suitable to be enabled by default (e.g. not syntax-guarded); a better understanding of this is part of what Arnaud words towards to. So I don’t have a great answer; I am not keen on having to write Maybe not including |
I think David's point is that when I build my 800-moudule, 5-person project, I might like an end-to-end check that I'm not using any experimental features, via |
Indeed, the “large project usecase” is convincing, and there an off-by-default
which also declares the project-wide whitelist of experimental extensions that are ok to use, but still get turned-on individually in the appropriate files. |
I am, however, not fully convinced this buys us that more over a simple This proposal has the benefit of providing an initial categorization (mature/experimental) that only has to be refined, rather than written from scratch, and it comes with the linting feature. So I’m not opposed on that grounds, but don’t think I’d miss a lot if I had to implement this using hlint. |
There are some further benefits over the
|
I think that you have indeed not gained anything. However, someone who has no idea what
I think that this is absolutely true if you're a Haskell expert who understands the tradeoffs of |
I think that, after having it |
In the general case I think we as a community should reach for quicker moving and less invasive changing tools like
Now that said, context is extremely important. For this case in particular, I think the external tooling approach is subpar. The following reasons from @david-christiansen are all apart of it:
In my opinion the last one is really important. Here the categories come from the ghc project itself, which would be the authoritative source for information for the status of extensions as provided by ghc. If someone outside of ghc says something is experimental, or deprecated, that doesn't give nearly the same kind of information as this coming from ghc itself. Further, I would assert that warning on |
The hlint version also doesn't really help GHC developers. @int-index and I are in the process of:
We all intuitively know one of these is very mature and the other isn't, but its rather awkward that this isn't written down. This would make it explicit.
So "mature" means it is one of these sets, and "legacy" means it is in addition is no longer in the most recent one? I suppose that works, but I do like tracking this information per extension. The causality running one way or the other is not entirely also clear to me. A few things:
If we are clever about exactly what we write down, we might not need to "denormalize" anything. And to the extent we do denormalize, we can have tests that ensure nothing drifts out of sync. |
|
||
However, it also seems plausible that new knowledge might from time to time cause a mature extension to once again be considered experimental, e.g. in the face of soundness bugs or subtle interactions with other features. We also do not rule out any transition explicity to allow for unforeseen circumstances. | ||
|
||
For existing, or future, language sets such as `GHC2021` or `Haskell98`, it is expected that none of the contained extensions would be `Experimental`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nor Deprecated
nor Legacy
, I would have thought? Or at least, they shouldn't have that status when the language set is created.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haskell 98 certainly includes NPlusKPatterns
, which I think may end up in one of those categories. And over time, it doesn't seem implausible that we'd declare legacy an extension that had been in one of these default sets (after a very, very long notice period, of course)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, things that are in a set can become deprecated or legacy, but when we create a set we probably shouldn't include anything in those states? e.g. GHC2021 does not contain NPlusKPatterns
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It certainly seems like a good idea to as a matter of policy say that a new language set does not contain legacy or deprecated extensions. However, if a language set should be added after the fact for some reason, then perhaps it would include a legacy extension. Maybe resolving if a policy should exist for this and what exactly that would be is worthy of a separate discussion?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm loathe to impose policy here. I think that the people building such a set can take these extensions into account, and that any policy is either redundant or the kind of thing that would be set aside anyway in the situation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One more case: the Haskell98
extension set presumably came into existence after some of its component parts were broadly acknowledged as design dead-ends (and thus Legacy
). Introducing this set is nonetheless useful, as it helps people improve compatibility with older code. Here, any policy could have been set aside, but making a policy seems to not buy us anything. I certainly agree that we should be surprised if e.g. GHC2035
includes any deprecated extensions when it's introduced in 2035, but how will a written policy actually help?
I have to say I would rather not link this to the much more ambitious efforts to construct a new framework for understaning extensions. This very modest proposal seeks to in effect codify our existing practice so that they can be better understood more widely and better managed. If we could reach agreement on this proposal (see the early comments) then that could help clarify some things for the more ambitious undertaking. |
I agree. The problem that the effort I'm leading is trying to solve is different, and largely orthogonal to this one (it's essentially about being more principled when answering questions like “should X be an extension”, or “should these two extensions be a single extension”). The discussion ebbs and flows, and the discussions intersect. But the harder discussion oughtn't block the easier one. |
…GHC 9.8! As written, ghc-proposals#448 has a venerable old extension, `-XScopedTypeVariables,` imply a brand-new extension `-XTypeAbstractions`. This was done for backwards compat, but in light of the sentiment expressed in e.g. ghc-proposals#601, I think this is a bad mechanism for backwards compatibility. There is a clear desire to separate more stable / less stable extensions, and an implication like the above from stable to unstable flagrantly violates it. A new backwards compatibility mechanism is proposed instead. I am sorry to say I noticed this rather late, and the implication I wish to change is ready to ship in **GHC 9.8**! As such, we need to decide on this quickly.
…GHC 9.8! As written, ghc-proposals#448 has a venerable old extension, `-XScopedTypeVariables,` imply a brand-new extension `-XTypeAbstractions`. This was done for backwards compat, but in light of the sentiment expressed in e.g. ghc-proposals#601, I think this is a bad mechanism for backwards compatibility. There is a clear desire to separate more stable / less stable extensions, and an implication like the above from stable to unstable flagrantly violates it. A new backwards compatibility mechanism is proposed instead. I am sorry to say that I noticed this rather late, and the implication I wish to change is ready to ship in **GHC 9.8**! As such, we need to decide on this quickly.
#604 Is a small amendment to an existing proposal to change something that I think would be (or ought to be) caught by this: a more mature extension implying a less mature extension. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some polishing suggestions
|
||
### 2.1. Categories and Lifecycle | ||
Language extensions will be classified into the following categories | ||
* `Stable` extensions are considered to be finished and are not expected to undergo regular changes. These features can be used without worry of unexpected changes, and they are not known to contain serious design or implementation deficiencies. Any breaking change to a stable extension will be announced well in advance of the change being made, with a migration path provided if possible. For an extension to be classified as `Stable` it must be considered `Stable` when used in combination of all possible, non-mutually exclusive, extensions that are already `Stable`. This ensures any extension that is `Stable` will be have the same use without worry when combined with any other extension in the set, while allowing for mutually exclusive extensions to be added. Ideally, no breaking change will be made to a `Stable` extension, with incompatible changes resulting instead in a new, related extension, that is possibly mutually exclusive with the existing one, to enable smooth migration. Some extensions in this category might be `MultiWayIf`, `MonoLocalBinds`, and `ViewPatterns`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* `Stable` extensions are considered to be finished and are not expected to undergo regular changes. These features can be used without worry of unexpected changes, and they are not known to contain serious design or implementation deficiencies. Any breaking change to a stable extension will be announced well in advance of the change being made, with a migration path provided if possible. For an extension to be classified as `Stable` it must be considered `Stable` when used in combination of all possible, non-mutually exclusive, extensions that are already `Stable`. This ensures any extension that is `Stable` will be have the same use without worry when combined with any other extension in the set, while allowing for mutually exclusive extensions to be added. Ideally, no breaking change will be made to a `Stable` extension, with incompatible changes resulting instead in a new, related extension, that is possibly mutually exclusive with the existing one, to enable smooth migration. Some extensions in this category might be `MultiWayIf`, `MonoLocalBinds`, and `ViewPatterns`. | |
* `Stable` extensions are considered to be finished and are not expected to undergo regular changes. These features can be used without worry of unexpected changes, and they are not known to contain serious design or implementation deficiencies. More specifically | |
* For an extension to be classified as `Stable` it must be considered `Stable` when used in combination of all possible, non-mutually exclusive, extensions that are already `Stable`. This ensures any extension that is `Stable` will be have the same use without worry when combined with any other extension in the set, while allowing for mutually exclusive extensions to be added. | |
* Ideally, no breaking change will be made to a `Stable` extension. Instead, it may be better to add a new, related extension, that is possibly mutually exclusive with the existing one, to enable smooth migration. | |
* If, however, a breaking change is made to a stable extension, it will be announced well in advance of the change being made, with a migration path provided if possible. | |
* Some extensions in the `Stable` category might be `MultiWayIf`, `MonoLocalBinds`, and `ViewPatterns`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"This ensures any extension that is Stable
will be have the same use without worry " doe not parse.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any thoughts on this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought the wording changed slightly in the last update but I must have put the existing one back before committing.
Perhaps:
This ensures any extension that is
Stable
will have the same stability properties when combined with any other extension in the set, while allowing for mutually exclusive extensions to be added.
?
|
||
* `Experimental` extensions are undergoing active development, or have consequences that make it impossible in practice to avoid breaking changes. The syntax and semantics that are enabled by the extension are likely to change regularly. It is expected that most new language extensions will begin as experimental, while the developers and the community gain experience with their use. Despite being open to breaking change, an `Experimental` extension must be `Deprecated` prior to removal. Some extensions in this category might be `RequiredTypeArguments`, `RebindableSyntax`, and `Arrows`. | ||
|
||
* `Deprecated` extensions are considered to be design or implementation dead ends, and should not be used in new code. Deprecating an extension means that GHC intends to remove support for it in a future release (though this decision may be revised in the light of user feedback). When an extension is deprecated, the user's guide and the compiler warning _must_ include a statement about the longevity of the extension, though this need not necessarily commit to a concrete time for removal. Additionally, the user's guide and the warning should direct users to information about migrating away from the deprecated extension. Any extension will be deprecated prior to removal. Some extensions in this category might be `OverlappingInstances`, `Rank2Types`, `RecordPuns`, and `TypeInType`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* `Deprecated` extensions are considered to be design or implementation dead ends, and should not be used in new code. Deprecating an extension means that GHC intends to remove support for it in a future release (though this decision may be revised in the light of user feedback). When an extension is deprecated, the user's guide and the compiler warning _must_ include a statement about the longevity of the extension, though this need not necessarily commit to a concrete time for removal. Additionally, the user's guide and the warning should direct users to information about migrating away from the deprecated extension. Any extension will be deprecated prior to removal. Some extensions in this category might be `OverlappingInstances`, `Rank2Types`, `RecordPuns`, and `TypeInType`. | |
* `Deprecated` extensions are considered to be design or implementation dead ends, and should not be used in new code. Deprecating an extension means that GHC intends to remove support for it in a future release (though this decision may be revised in the light of user feedback). | |
* When an extension is deprecated, the user's guide and the compiler warning _must_ include a statement about the longevity of the extension, though this need not necessarily commit to a concrete time for removal. Additionally, the user's guide and the warning should direct users to information about migrating away from the deprecated extension. | |
* Any extension will be deprecated prior to removal. | |
* Some extensions in the `Deprecated` category might be `OverlappingInstances`, `Rank2Types`, `RecordPuns`, and `TypeInType`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Formatting bug. The latter two bullets are over-indented
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, the last update should fix the formatting issue.
|
||
Above we list expected categorizations of several extensions based on statements in the user's guide. We do not attempt to prescribe any particular categorizations as part of this proposal and simply provide a small number of expectations from the perspective of someone reading the existing documentation. | ||
|
||
The above places some restrictions on the transitions included in the extension lifecycle. The following transitions are also expected to be included: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please list all transitions. Otherwise what does "also" mean, precisely?
Or, perhaps better, list the excluded transitions, with some rationale.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am keen to list all allowed transitions; or all disallowed transitions. Listing some of each, leaving others unspecified is not a happy state.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated to list all transitions, including those not explicitly included or excluded in the proposal.
* `Stable` -> `Legacy` | ||
* `Legacy` -> `Deprecated` | ||
|
||
However, it also seems plausible that new knowledge might from time to time cause a stable extension to once again be considered experimental, e.g. in the face of soundness bugs or subtle interactions with other features. We explicitly allow for more transitions to allow for unforeseen circumstances. Restrictions are places on removal only. With this we aim to balance predictibility and flexibility. The consideration of both is important as extension classifications are first and foremost a communications channel between language designers, compiler developers, and users. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
" Restrictions are places on removal only"
What precisely is the restriction?.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any thoughts on this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I updated the set of included transitions to be more complete and added the exclusion list.
* `Stable` -> `Legacy` | ||
* `Legacy` -> `Deprecated` | ||
|
||
However, it also seems plausible that new knowledge might from time to time cause a stable extension to once again be considered experimental, e.g. in the face of soundness bugs or subtle interactions with other features. We explicitly allow for more transitions to allow for unforeseen circumstances. Restrictions are places on removal only. With this we aim to balance predictibility and flexibility. The consideration of both is important as extension classifications are first and foremost a communications channel between language designers, compiler developers, and users. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
" We explicitly allow for more transitions". More than what? Can you make this precise?
Maybe you have in mind a set of "normal" transitions, ones that are "exceptional" and ones that are "disallowed"? I'm really not sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated For this and the above to note the excluded transitions explicitly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't see the change here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The explicitly excluded transitions are listed in the block right above this paragraph now.
|
||
However, it also seems plausible that new knowledge might from time to time cause a stable extension to once again be considered experimental, e.g. in the face of soundness bugs or subtle interactions with other features. We explicitly allow for more transitions to allow for unforeseen circumstances. Restrictions are places on removal only. With this we aim to balance predictibility and flexibility. The consideration of both is important as extension classifications are first and foremost a communications channel between language designers, compiler developers, and users. | ||
|
||
For existing, or future, language sets such as `GHC2021` or `Haskell98`, it is expected that none of the contained extensions would be `Experimental`. However, this proposal does not seek to impose any particular policy on the inclusion of extensions into language sets - the developers and the steering committee are always in the best position to make a decision about a concrete extension and extension set. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"language edition" not "language set"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, updated!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It still says "language set"
|
||
### 2.2. Documentation | ||
|
||
The user's guide for each extension documents where it is in the extension lifecycle. We expect this to be next to the "Since" and "Implied by" fields in extension documentation. Additionally, the user's guide should provide a history of the extension's sojourn through the various states, and the GHC versions in which it went from being experimental to stable, or from stable to deprecated. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you pull out two particular transitions for special mention? Why not just say the user guide should document the GHC version in which each transition was made?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've updated the wording to make it more clear the guide should say when each transition was made and that two called out are examples.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see a change here
From a process point of view I think it makes sense to keep the same shepherd by default when a proposal is revised. Of course @simonpj if you'd prefer someone else takes it on, you are welcome to ask for it to be reassigned. But otherwise I think we can discuss it here and you can bring a recommendation to the committee again in due course. Regarding the current state of the proposal itself, I'm generally supportive of accepting this and then bringing forward a new proposal with concrete classifications (as I've been trying to work on in the documents linked from #635). Some big picture comments:
|
In the interests of getting something done, I'd be inclined not to widen the scope of this proposal. I'd be quite happy to merge Does anyone else have a view? Or @telser ? |
I agree with this. Making some progress feels important even if it isn't as broad as many, myself included, would ideally prefer.
It has become clear from conversations that the state of extensions is critical. While I certainly believe that for GHC it is not pressing to remove some of these extensions, for a subset of the community the frustration with extensions is extreme. In talking with those users as part of forming this proposal, it was a very loud complaint that extensions do not go away, causing ever more discussions. There are two actions that seem lightweight and form an olive branch to that subset of users. First is removing some of these extensions that have been marked as deprecated for years or decades, or are undocumented. Second being very clear on the status of extensions by having two categorizations here. Let some of the extensions be |
Interesting. Can you say what extensions, specifically, caused these loud complaints? And what were the complaints about? Extensions that aren't used (except perhaps by a small minority) should not cause any trouble -- but perhaps they do? Specifics would help, since that makes the case for a legacy/deprecated distinction. My anxiety is that the moment we say "X will go away", a new set of loud complaints will emerge about its absence :-) |
Extensions that are not widely used do cause problems. They increase the surface area of the language and introduce more points of team debate. In some cases re-litigation of this happens every time a team gets a new member.
Most of the complaints are more about the volume rather than having certain functionality. The most frequent is probably the hardest to solve, and out of scope for this proposal. However that seems to me to make the olive branch for handling others even more important. Generally speaking the complaints are as follows:
|
As an aside: |
@Tritlo That's extremely interesting! Some time ago there was a discourse thread and I don't recall anyone speaking up about concrete usage. Either way though the point of my comment and this entire proposal is to not decide any specifics. Any particular extensions in my comment are only to provide illustrative examples. So this is interesting but I'd greatly prefer it if we do not get into any particular extensions further on this particular proposal to avoid any particular extension causing us to not have progress on this, extension agnostic proposal. |
@telser I have made various suggestions, some of which you have responded to, but not all. I understand that you want to stick to the Legacy/Deprecated distinction. Fine. We can vote on that. Please ping me me when you are ready. I have not yet made a recommendation to the committee, pending your final version. |
What do we gain by actually removing them, though, rather than simply emitting a warning when they are used? I don't think many teams are debating whether to enable |
Actually to make this clearer I have changed the status to "needs revision". Let me know when you want to resubmit it. Everyone: it would help the committee to have views from the community about whether you actively want a distinction between My own instinct is to keep it simple, have a single category; but Trevis's instinct is different. Hence wanting community views. |
I think there is some meaningful action-guiding difference for a user between An analogy might be between warnings in
The cost of merging
|
I think it's unwise to merge But for extensions which are actively recognised as mistakes or are completely obsolescent, I think having a |
I've been mulling this over. I can see that there is a useful distinction here to signal to users. The reason I don't like the
In this case my preferred course would be to say |
|
Well, the current text says:
So yes there are caveats, but the intention is for it to be removed. If there is consensus that "may be removed" is fine, then I'm happy, but I think we should reflect that in the text, e.g.:
|
As far as I can tell, there is some user sentiment in favour of offering a Deprectated/Legacy distinction, and no argument against except Occam's razor. I'm content to follow user sentiment here. Status check: the proposal is in "Needs revision" state, awaiting the author (currently @telser) to revise and resubmit. Correct? |
I believe so. I'd appreciate @telser's comments on my suggestion in #601 (comment). I've updated my spreadsheet with a rough draft categorisation of extensions based on a variant of this where I distinguish between Internal and Experimental (explained in more detail in the accompanying document). In particular, |
All possible state transitions are now enumerated, specifically including those that are not prescribed in the proposal. Some formatting fixes with overly indendented list items. Changes deprecated to say extensions *may* be removed, but not that they *will*.
455bd04
to
e0c66e0
Compare
I've updated the proposal to reflect the "may be removed" sentiment. Though I fear, at least some of, the users who have spoken at length with me on this will be disappointed in this change. However, if this change is acceptable to @adamgundry, I'm happy to resubmit. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @telser! This is looking good to me.
I've updated the proposal to reflect the "may be removed" sentiment. Though I fear, at least some of, the users who have spoken at length with me on this will be disappointed in this change.
I would love to understand better the source of this disappointment. Perhaps there are ways to ameliorate it (e.g. would dropping Deprecated
extensions from the list of extensions in the docs help?).
* (does not exist) -> `Deprecated` | ||
* (does not exist) -> `Legacy` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not convinced about excluding these. Something we have been known to do in the past is to introduce a new extension name for existing functionality (of the base language or another extension) that is being deprecated or otherwise restricted. For example:
DeepSubsumption
was arguablyLegacy
when it was introduced, because its functionality was already present in previous releases but we wanted to move towards a world in whichNoDeepSubsumption
became the default. (I'm not sure whether we would have consideredNoDeepSubsumption
to beExperimental
orStable
on its introduction.)- If we want to partially deprecate an extension, I think the right way is to split it into multiple extensions and introduce one or more of them as
Deprecated
(e.g. I can imagine splitting upIncoherentInstances = IncoherentInstanceDeclarations + IncoherentClassRoles + IncoherentSolving
withIncoherentInstanceDeclarations
beingDeprecated
).
So I'd suggest moving these to the "discretionary" category.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not convinced about excluding these. Something we have been known to do in the past is to introduce a new extension name for existing functionality (of the base language or another extension) that is being deprecated or otherwise restricted. For example:
DeepSubsumption
was arguablyLegacy
when it was introduced, because its functionality was already present in previous releases but we wanted to move towards a world in whichNoDeepSubsumption
became the default. (I'm not sure whether we would have consideredNoDeepSubsumption
to beExperimental
orStable
on its introduction.)
This is a really good point.
- If we want to partially deprecate an extension, I think the right way is to split it into multiple extensions and introduce one or more of them as
Deprecated
(e.g. I can imagine splitting upIncoherentInstances = IncoherentInstanceDeclarations + IncoherentClassRoles + IncoherentSolving
withIncoherentInstanceDeclarations
beingDeprecated
).
I would have expected all of them to be Experimental
at first. That way if the way IncoherentInstances
was cut needed to change then it is less problematic as the entire set was Experimental
. To be more concrete, if it was realized after being "in the wild" that it is better defined as IncoherentInstances = IncoherentDeclarationsAndClassRoles + IncoherentSolving
or maybe IncoherentInstances = IncoherentInstanceDeclarations + IncoherentClassRolesAndSolving
then the only removals/changes would have been made to Experimental
extensions.
That said, I'm fine with moving this to the "discretionary" category.
## 2. Proposed Change Specification | ||
|
||
### 2.1. Categories and Lifecycle | ||
Language extensions will be classified into the following categories |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A small point, but what about classifying "negative" extensions? For example FieldSelectors
was effectively Stable
when introduced (whereas NoFieldSelectors
was definitely Experimental
).
I guess the simplest thing would be to say that we classify both the enabled and disabled states, but the normal case is for an extension to be Stable
when disabled (with NoFieldSelectors
being one of a small number of exceptions).
One other thought: what should the existing We could say that |
I would be in support of a flag for legacy in addition to deprecated, but I also think that is out of the scope of this proposal. |
This proposal suggests a defined lifecycle for language extensions, to more clearly communicate tacit community knowledge about which extensions make sense in which contexts. Additionally, it proposes a set of compiler warning flags that empower users of GHC to choose their own level of tolerance for language extension changes.
This proposal is a product of the Haskell Foundation's Stability Working Group.
Rendered