Extensions and Cabal

Ian Lynagh igloo at earth.li
Fri Mar 23 17:13:19 EDT 2007

Hi Cabalites,

I fear this may be contentious, but here goes anyway...

Currently we have (at least) 4 ways that extension E can be enabled for a
given file in a cabal package (using GHC as an example, if -fe enables E):

1. foo.cabal: Extensions: E
2. foo.cabal: Ghc-Options: -fe
3. Foo.hs: {-# LANGUAGE E #-}
4. Foo.hs: {-# OPTIONS_GHC -fe #-}

Ideally, from cabal's point of view, we would use option 1. This way
cabal knows about the extensions, so can fail early if we don't support
the necessary extensions to build something.

2 and 4 are inferior variants of 1 and 3 respectively; the only case I
can think of where you might want to use them is if cabal doesn't know
about the extension yet. This could be solved by a --language=E flag
that GHC treats identically to -fe. Obviously cabal can't check that GHC
supports this extension in advance (so would have to assume that it
does), but at least we no longer have any need to enable extensions with
method 2 or 4. We could also then have Cabal always pass a
--no-extension-flags flag, which would mean that GHC would reject -fe.

That wasn't the contentious bit, so hopefully you aren't too inflamed

Suppose we agree that we should only use method 1; there are a number of

* If someone uses method 3, no alarm bells will sound. The package will
  continue to build where it can be built.

* The same set of extensions is used for every module. For example, if
  you want to allow overlapping instances in one particular place[1]
  then you must allow them everywhere.

* If you want to load one of the modules in ghci, say, then you need to
  tell it what flags to use.

Thus I propose that the .cabal file actually specifies what extensions
the modules are /allowed/ to use, but does not actually enable them.
They would then be enabled by LANGUAGE pragmas in the modules as
necessary. So, if the .cabal file says "Extensions: E, F" then the
modules will be compiled with
    --no-extension-flags --allowed-extension=E,F
and if a module has "{-# LANGUAGE E #-}" then only extension E would be
enabled for that module. If a module has "{-# LANGUAGE E,G #-}" then
compilation would fail as extension G is not permitted.

Any comments? Criticisms? Flames?


[1] Currently we can only specify this to a file-level granularity, but
    in principle you could imagine more localised pragmas, like we have
    for unboxed fields.

More information about the cabal-devel mailing list