GHC2024 – community input

I have started the process where the GHC Steering Committee decides if we should have a GHC2024 language edition, and what it should contain. @MangoIV rightfully reminded me that when we laid out the process three years ago, we said we’d hold a community poll as well.

So here we go!

I will not bother you with listing every possible extension, but instead narrowed the poll down to those extensions that were actually nominated. In addition, I added those extensions didn’t make the cut for GHC2021 by a margin of 3 votes or less, to put the numbers in perspective.

Please also have a look at the GHC2024 proposal, it lists pros and cons for every nominated extension.

So here we go:

Which extensions should be part of GHC2024

  • DataKinds and TypeData
  • DefaultSignatures
  • DerivingStrategies
  • DisambiguateRecordFields
  • ExplicitNamespaces
  • GADTs with MonoLocalBinds
  • ImpredicativeTypes
  • LambdaCase
  • RoleAnnotations
  • TypeFamilies
  • BlockArguments
  • OverloadedStrings
  • RecordWildCards
  • NegativeLiterals
  • UnicodeSyntax
  • DerivingVia
  • FunctionalDependencies
  • NoMonomorphismRestriction
  • NumDecimals
  • ViewPatterns

0 voters

(Unfortunately, Discourse requires every vote to at least select one, and I can’t add more than 20 options, so there is no space for a “None” option :man_shrugging: .)


Thank you very much for this @nomeata !

I like the fact that more extensions that do not degrade the user experience, like NegativeLiterals, DerivingStrategie and TypeData are candidates to get in!

I’d be much more cautious about OverloadedStrings, by experience, because it can be much, much more confusing to see a type error related to Foldable, instead of just “You tried to use Text instead of String!”.
Having it at the top of the file explicitly really does help reading a module later on. :slight_smile:


Ooh, the five I chose are the top five so far. It’s great to be in the popular group! If TypeFamilies, BlockArguments or OverloadedStrings get in I will be very sad :frowning: . We should really get a better implementation of type level functions before enshrining them in a GHC20xx release. BlockArguments are just syntactically too baffling for me and I really don’t want to inflict them on Haskell newbies. OverloadedStrings is just far too powerful. I would rather have StringLiteralsAreText (even though it doesn’t exist (yet)).


For the ExistentialQuantification + GADTSyntax = GADTs problem I’d prefer solution number three: removing ExistentialQuantification.

What are the reasons to choose NegativeLiterals over the more recent LexicalNegation? I thought the latter was just generally better and behaves more like what users expect.

I think the fact that DerivingVia leaks implementation details (that it is coercing the methods) in error messages should disqualify it. I don’t think it is mature yet.


That’s so true… on the other hand, I really want to bang my head against the keyboard when I get a “cannot match String with Text” :sweat_smile: Maybe my vote for it is an act of rebelty against the compiler.

Why people has something against FunctionalDependencies :grinning_face_with_smiling_eyes: ? are they harmful?

1 Like

I think FunctionalDependencies are very complicated and often confusing. And I believe they are about as powerful as TypeFamilies, which I also think should be used with care. I don’t mind having to put a pragma at the top of my files to be able to use them.


Because I copied from the list from 3 years ago, I guess :slight_smile:


Honest question: why are DataKinds and TypeData being lumped together?

I mean, I get that they’re similar extensions, but I’ve been migrating to having TypeData on and DataKinds off, because TypeData keeps the separation between types that can be types of values and types that only exist to do type gymnastics, and I like to be told by the compiler when I’ve screwed up that separation.


Because they were proposed together. If you want to refine the section of the proposal to explain why one should choose one over another, please do suggest an edit at GHC2024 by nomeata · Pull Request #613 · ghc-proposals/ghc-proposals · GitHub.

That’s so true… on the other hand, I really want to bang my head against the keyboard when I get a “cannot match String with Text” :sweat_smile: Maybe my vote for it is an act of rebelty against the compiler.

You’re sentenced to teach Haskell newbies with OverloadedStrings enabled implicitly! :woman_judge:


I honestly find having to put a $ in front of a lambda merely something you get used to, not something that is intuitive.


Yeah! It’s surprising to me too just how unpopular BlockArguments is; it’s usually the first extension I turn on when I’m messing around in a sandbox.

In Haskell (and similarly in other languages with bare function application), I’ve always been inclined to view function application syntax as a fictional infixl 10 ε operator¹, but with fussy restrictions on what the right operand can be. BlockArguments removes the fussy restrictions and makes the language simpler, to my brain at least. (And also to the BNF grammar, judging by the BlockArguments documentation.)

¹: Ha, that’s even more or less how the documentation for ($) describes function application!


I vote for: None.

And I need to write at least 20 chars.

I’m also confused there’s no option to vote for removal of extensions.

It seems quite a biased vote.


Less pithily than what @hasufell wrote, I think @nomeata’s goal with GHCXXX was to get us away from language extension soup and towards a unified language we can all agree on. I think that is good, and I express similar sentiments in

But the intermediate step of debating individual extensions feels really odd to me. Especially coupled with the fact that the inevitable drift is to enable more and more extensions + some folks’ expectations that the GHCXXXX would each be compatible extensions of the last rather than a chance to batch breaking changes.

I am hesitant to post a “I feel weird about this!” comment without having a short-run actionable alternative, but…I do feel really weird about it. I guess I just hope that this really is a stepping stone, and soon we can get back all the way to actually designing new GHCXXX holistically rather than cobbling together spare parts from 30 years of unculled experiments.


Yeah I agree. I hesitated to vote because really I’m just voting for the ones that I have happened to have learned and enabled, I have no idea of performance trade-offs or alternative paradigms being researched for example. It’s convenient to be able to specify ghc20xx and get most things and reassurance of compatibility between them.

In general for technical decisions like this, democracy is efficient / destructive. The people who are stewarding the performance, safety, compiler feedback, … etc should make the call. Language extensions were intimidating at first, but they provided opportunities to learn step by step and they create breadth for researchers to experiment with new ideas. As long as it’s considered a convenient bootstrap rather than an immutable extension binding future Haskell development then it’s all good.

1 Like

Well, this vote won’t decide, but it adds information for the committee to ingest. It’s useful to see that support for LambdaCase is near anonymous, but that I’m almost a lone fan of allowing Unicode syntax.

As for voting none, that’s an unfortunate restriction of the poll system here, I tried to set the minimum to 0. Maybe I should have asked the admins to allow more options and add an explicit “none” option.

As for removing extensions relative to GHC2021: that’s certainly possible, but so far none were proposed, and I didn’t want to clutter the poll too much. If anyone has a good arguments for removing something, please add them to the proposal!

I personally see GHC20xx not primarily as “the Haskell for beginners”, but “the normal contemporary Haskell”, suitable for everyone who’s not explicitly eager to try out new or experimental language features.

There might be a world where Haskell has explicit language levels, but it would probably be more than just a set of extensions, and also affect the visible Prelude, error messages etc.


Yes, it could be a case me just not getting used to it yet, but I do like the idea that there is some explicit separator that indicates function application when the argument is more complicated than a variable. I mean, I even find

f myRecord { myField = newValue }

confusing! To me it’s much clearer to read

f (myRecord { myField = newValue })

Why are PatternSynonyms not on the list? Would be my top prio after LambdaCase


BlockArguments are great!
(But maybe that’s due to my Agda training…)


This is a fun one because it’s the opposite of my experience: as a beginner I found OverloadedStrings an anchor for my sanity but now I only enable it on a module basis.

But yeah I agree it’s “too powerful”, on balance.