GHC Steering Committee seeks input from industrial Haskell users

Realistically, the extension lifecycle should go from experimental->stable and that’s it.

If a user uses a stable extension they should expect that it will work out for subsequent releases, even if it becomes legacy or deprecated.

1 Like

That is the happy path, which in the proposal is experimental → mature. But deprecated & legacy are for sad paths, namely how to scheduling sunsets of some extensions.

From how I read, “mature” ones have high assurance for you in that matter. “legacy” ones may also work, but it’s also a warning to you that you might want to move away from it.

hmm, that’s probably the intention of extension sets: Haskell 98/2010, GHC 2021?

Thus my concerns that the extension sets are excluded from the proposal instead af being at the centre of it.

1 Like

To be clearer, what I meant was being legacy or deprecated is a tag associated with the path, and not the path itself. Once it hits mature and users start using it, there should not be any breaking changes even if it goes into legacy or deprecated, which means that these apis should remain there for some defined X versions from the warning until its confirmed that nobody uses it at all (and since this is hard to confirm, in practice this means nothing is removed once it hits mature).

This level of guarantee allows industry users to use what they want safely without fear of needing to dedicate time to refactor something because it has become deprecated. The industry can trust mature extensions are well designed with long lasting semantics.

2 Likes

There was an extension called MonadFailDesugaring which was added in 8.0.1, enabled by default in 8.6.1 and removed in 9.0.1 (I think, can’t find it in the release notes). I suppose it could be considered mature in GHC 8.6.1?

Maybe we could distinguish “superseded” (when there is a new extension that includes the same functionality and there is a clear migration path, like the case of MonadFailDesugaring) and “deprecated” (when the idea is flawed and/or abandoned).

Not sure this helps anyone though.

(I only skimmed the proposal, apologies if this has already been considered or discussed)

The point of superseded is that you can just disable the extension without having refactor anything, a bit like redundant imports.

About all of this proposal that might me the only one thing i will fond useful (unless we get instead a redundant extension warning)

My company uses Haskell to deploy web services. I think we find this useful for a couple of reasons:

  • we would default to only allowing mature extensions, to avoid future maintenance work. Ideally this could be changed in a per-file and per-package basis, eg if we really wanted to use LinearTypes in one module.
  • We would find where we were using deprecated extensions before they were removed, enabling gradual migration away from them.
2 Likes

You need to be clear to them that this means that mature extensions should not be changed at all or only go into legacy only, not deprecated.

It is not apparent currently that mature extensions wont get removed in future releases.

I am not sure we want to promise that, and the proposal actually says

Any breaking change to a mature extension will be announced well in advance of the change being made, with a migration path provided if possible.

If we could predict the future, then maybe we could make an absolute statement, but in light of more information, I hope we can still make any change – with due process. That’s the point of Deprecated, isn’t it?

I am not sure we want to promise that, and the proposal actually says

If this cannot be promised for certain LTS major or minor versions, as noted above by @maxigit then marking something as “mature” has no difference from being “experimental”. “High assurance” isn’t something that can be quantified or planned for.

If we could predict the future, then maybe we could make an absolute statement, but in light of more information, I hope we can still make any change – with due process. That’s the point of Deprecated, isn’t it?

Languages suitable for wider enterprise adoption often have long-lasting semantics, especially for LTS versions (up to X amount of years), and I believe we can all learn something from the Python 2->3 fiasco. This is not about “predicting the future”, this is about committing to stability for a certain amount of time that can be factored into planning and reducing the risk of using Haskell in production.

1 Like

Stability commitments are absolutely important.

Today, some extensions are known to be basically “finished”, and considered unlikely to ever change. Others are considered to be unfinished, subject to more or less rapid iteration as the contact with real users casts light on the design. It is highly unlikely that one of these “finished” extensions would be removed or drastically changed, certainly not without a long deprecation cycle. On the other hand, rapid iteration from release to release of a new feature is normal and expected.

How are users to know which is which? This proposal seeks to provide a means by which it can be communicated, and by which changes to that communication can be checked in CI.

I totally get that it doesn’t solve every problem - there are lots of things we can do to improve things! Do you think that this makes things better, though?

1 Like

The short answer is no, for me it’s trying to solve a problem which in my experience doesn’t exists.

I’ll explain. GHC is the most conservative software I ever seen. We use to have a joke in one of my previous work “temporary means forever”. That stands for GHC. I’ve never seen any extension, experimental or not being changed or removed. One would expect that once a space design has been explored and battle tested all the mini extensions composing a feature would be merged into one. That doesn’t happen. Or we could think that once it’s been stabilised it actually becomes the default and the extension becomes “obsoletes”, it doesn’t happen either because GHC has to follow the specification.
Fair enough, we could then expect that once the spec get updated (every 12 years) then the previous anguage got forgotten about and all adopted extionsion become obsolete (or better removed). That doesn’t happend either. GHC is still Haskell 98 plus 100 something extensions (doing in ghci :set -X<tab> gives me 252 possibilites, I guess I should divide by 2 that left 126 extensions).

Nothing get ever removed from GHC, so as I industrial user I can confidently use any of them, I know they’ll still be there in 10 years. That’s what I’ve been doing and I have never been bitten by doing so.

I might not count as a industrial user. I’m the sole developper doing a in-house software with about 3 users (including me). I get (sort of ) paid for it, and it’s been used daily since 2016. It started with lts-5.9 and use now lts-20.*.

Now, I might be missing the quick change at the beginning of the life of an experimental extension, but so will other industrial user for the same reason. Upgrading to a new version of the compiler is a painfull process and I do as least as possible. The usual culprit are base being bumped, internal refactoring breaking TH , abadonware package needed care etc …

So I wait for things to settle before upgrading to a new version of GHC. By that time every extensions availbale will there for eternity.

2 Likes

(Disclaimer: I’m not an industrial user)

RankNTypes was infamously changed recently which broke a whole lot of code and spawned the new DeepSubsumption extension that undoes the change. Also, ExistentialQuantification has changed and will probably soon change again, see the other thread (that is a rather trivial change, but it could break code).

GHC2021 has become the default. Removing old extensions just breaks existing code for little reason. I guess you could argue it would improve discoverability of the remaining extensions, but that doesn’t weigh up against the breakage it would cause; the categorisation proposed here would be a better way to improve discoverability in my opinion.

2 Likes

It is still an extension set. What I mean by remove is when an extension is adopted the doc could me moved the corresponding part in the syntax manual and the fact that it used to be an extension all forgotten. So that when you looked at Haskell 2010 for example you have a standalone thing, not Haskell 98 + x y and z.

3 Likes

I agree. I hope we will get to the point where the latest GHC20xx is perceived not as a set of extensions, but as a wholesome language edition, and the documentation structure hopefully will support that.

The old editions (Haskell2010, GHC2021, all the various extensions to these base lines) may still be supported to not break code lying around untouched. But hopefully developers who write fresh code, or who keep following the GHC20xx language editions with their actively maintained code, will no long have to think of so many extensions as features.

4 Likes

DatatypeContexts was removed by GHC2010 – chiefly so that we could experiment with bringing back the syntax but with more helpful semantics.

The current extensions around DuplicateRecordFields/Disambiguation and friends are regarded as experimental and liable to change. (That is, some of the implementation detail might change, not the proposed syntax: the implementation has run into some fishhooks.) And amongst the ‘friends’, NoFieldSelectors takes away a H98 feature.

Not true looking back over ~25 years; but I agree GHC has been getting more timid over the past (say) 5 years. Since DatatypeContexts is still ‘on the books’, there’s a risk someone’s still using it, so can we actually introduce something more helpful under that name?

Yeah. I’m pretty sure David’s o.p. wasn’t aimed at me (as a hobby user), so I’ve kept off this thread.

That’s right - this proposal was written specifically to address challenges we’d heard of from larger teams with mixed levels of Haskell expertise. If it helps enough of them significantly and doesn’t impose unacceptable costs on hobbyists, researchers, enthusiasts, and teams of experts, then I think it’s a win - if not, then back to the drawing board!

3 Likes

This it why I’ve been keeping out of the proposal itself.