This was my biggest frustration with Haskell the last time I used it, I find it sad that it doesn’t seem like they’re trying to fix it.
This was my biggest frustration with Haskell the last time I used it, I find it sad that it doesn’t seem like they’re trying to fix it.
Semi-related: I wanted to voice that while it can be tedious to enable extensions, what they do give us is a great way to explore several solution spaces without making the whole ecosystem commit to any in particular. Some become defacto, while some are more controversial and change the actual semantics of the language. The freedom to choose is both a burden and a gift though!
We have a fairly hefty haskell code base at work, and we never use LANGUAGE pragmas anywhere.
I’m aware there are other compilers but basically everyone uses GHC. So all these things that have to be turned on because they’re not “compatible“ with all the other compilers that no one else uses just add complexity for new users (and I suppose current users.)
Edit: I guess not useless, but over time rendered as anti-features
So in pragmatic terms, enabling/disabling "extensions" lets you prevent some unnecessary processing loads during compilation.
Obviously one can do everything in "vanilla" (no-"extensions") Haskell just like one could express everything in raw Lambda Calculus. Syntax sugars as always allow for reducing patterns of verbosity --- those provided by "extensions" tend to be such patterns-of-verbosity that don't always occur in-all-projects-all-the-time, just in enough-projects-much-of-the-time.
Most of the aversion to them seems kneejerk "but my other language had another (or none at all) approach to this" --- never understood the strong opinions about GHC extensions. "Other-language" typically also delights in a culture of repetetively verbose syntax itself and no such APIs to hack new language constructs into the compiler in a plug-and-play manner (without forking).
And yes one can enable these via cabal file or GHC -X flags, but there's something to be said for per-module pragmas: they only activate where needed, and it aids the code reader as to what non-vanilla syntactic constructs are used in the-module-at-hand.
If you think there are dozens then I challenge you to name a few ...
(I can't, off the top of my head, think of any but I don't deny there may be some.)
Haskell code with any extensions enabled is pretty much always compatible with Haskell code with any other extensions enabled.
(I only said "pretty much" to hedge my bets. I literally can't think of any case where extensions could make your code incompatible with other code across a module boundary.)
It’s nice there’s a way not to put them at the top of every single file but they still exist.
There must be some reasonable subset that basically everyone uses and should just be included in the language.
This is one of those things that seriously limits Haskell's growth. It's something for new users to bounce off of, and that contributes to Haskell's reputation as a write-only language.
Well, there is. The problem is that the last reasonable subset is 7 years old, and Haskell is evolving quickly.
There's a new standard scheduled to 2020.
The biggest complaints I see people make about Haskell are language extention lines and imports but for me these are both IDE issues. I'm not aware of many readable languages that end up with lots of imports for any non-trivial code.
Opt in extensions also allow you to avoid worrying about the longtail of backwards compatability.
That’s how you end up with situations like ‘null’.
Some of these extensions are nuts, too. They can make the type system behave in ways where it basically has to multivariate solve or do things that are overly clever. You probably don’t want that most of the time..
Some extensions can make existing code fail to compile, e.g. -XOverloadedStrings.
Some extensions are fairly specialised and their use can cause error messages that are confusing if you don't know what the extension does, e.g. -XAllowAmbiguousTypes.
Some extensions can cause certain pathological pieces of code to suddenly start behaving weirdly, e.g. if you turn on -XApplicativeDo for a type whose Applicative instance isn't lawful, but whose Monad instance is.
Of course, many, many extensions could be enabled by default without making the UX worse or restricting the set of allowed programs at all: a large section of Haskell users is likely in favour of enabling syntactic conveniences like LambdaCase or MultiWayIf, or automatic code-generation utilities like DeriveFoldable, DeriveTraversable, and so on. That's what Haskell Prime is for, I suppose.