Someone said something like this half jokingly : a “.hs” usually is half page of language extensions and imports.
Within the same project, often the same language extensions are used through out files anyways.
For these, I had just a quick thought here, I am curious how you think about it:
module ProjectConfig
( module GHC.LanguageExtensions.TemplateHaskell
, module GHC.LanguageExtensions.TypeFamilies
, module GHC.LanguageExtensions.OverloadedString
...
) where
import GHC.LanguageExtensions.TypeFamilies
import GHC.LanguageExtensions.TemplateHaskell
import GHC.LanguageExtensions.OverloadedString
...
-------
{-# LANGUAGE ImportableExtensions #-}
module A
import ProjectConfig -- this imports all those extensions due to ImportableExtensions
Now:
Language extensions can be in the import section of the program, some people may see that as less “offensive” than a laundry list of language extensions
But also you could reexport them to other projects, or even the consumer of your library if they enables “ImportableExtensions” feature. That could shorten the file length of the downstream usages, and potentially make your libraries easier to use if your libraries require a myriads of fancy extensions…
Some language extension could now benefit from the import syntax have “sub features” that you could further opt in.
My slightly trollish idea is that we should replace language pragmas with imports in the same way that Python does from __future__ import ... so that they are less intimidating.
People get intimidated by Haskell extensions because they’re described as extensions and configured with a special compiler directive, but many extensions really do just feel like importing an additional language feature; hell, with more expressive metaprogramming, a bunch of extensions would just be libraries!
Oh, this is very interesting! I’ve often heard non-Haskellers say “what puts me off Haskell is that all the extensions mean you have to learn several different languages”. As I Haskeller I know that’s not true: most extensions remove restrictions and very few are incompatible with each other.
Now I’m beginning to wonder: do people come to this point of view because extensions are enabled like {-# LANGUAGE RankNTypes #-}? Perhaps the very syntax we use to enable extensions makes people think they are switching to an entirely new LANGUAGE!
Using the word FEATURE instead of LANGUAGE would be a great improvement in making Haskell less intimidating. I’m not even sure why it’s called LANGUAGE in the first place because it doesn’t make any sense to me.
The default-extensions cabal field may be what you’re looking for. It’s less expressive since it applies to the whole component, but that’s usually fine.