Yes, thankyou Richard! I agree with virtually everything.
> B. Extensions that allow violation of some general principle that
holds elsewhere. These should be replaced by modifiers or pragmas and be
enabled locally. Examples: OverlappingInstances (this is already
done!), NoMonomorphismRestriction, DeepSubsumption(*),
UndecidableSuperClasses, NoMonoLocalBinds, etc.
I think it's worth making a further distinction according to whether the relaxation is thought to be unsound or not-well-founded for some reason (NoMonoLocalBinds, DeepSubsumption) and those that are well understood and not problematic at all (NoMonomorphismRestriction). The latter should just be treated like the syntax extensions: either experimental or enabled by default.
> C. Extensions that change the compilation pipeline. These need to remain as configuration flags. Examples: CPP, TemplateHaskell.
It's clear that CPP needs to remain as a flag because it does bad things to the syntax like breaking multiline strings and doing strange things to `##`. But it's less clear to me that TemplateHaskell is in this category. Isn't it just an extension that enables new syntax? Yes there are *practical* reasons why we might not want it on by default, because it makes compilation slower and whatnot, but isn't that all it is?
> D. Extensions that create variants of the language by changing
semantics of existing constructs. I'm not quite sure what to do with
these, but they probably need to remain configuration flags. Even better
if they could be enabled locally within a file, though. We should
probably try to avoid doing this in the future, though the pain may be
worth it. Examples: RebindableSyntax, Strict, OverloadedXXX, etc.
Again I think we could refine this. Clearly RebindableSyntax and Strict are not features that we would ever want to be on by default, but OverloadedStrings definitely is, and for me belongs in the category of language extensions that are either in GHC20xx now or will be later.
Cheers
Simon