More feedback on Haskell 98 modules from the Programatica Team

Simon Peyton-Jones simonpj@microsoft.com
Tue, 7 Aug 2001 11:50:03 -0700


Folks

The folk at OGI have continued the current trend of discovering=20
unspecified corners of Haskell 98.  That means taking some decisions,
and, as ever, I don't want to do that without giving you all a chance to
demur.   Nevertheless, I doubt this'll be controversial, because it's
all dark-corner stuff.

| 1) Sec 5.3.1:  In an "import A(x, ...)", the report tells us=20
| that x must be one of the names exported from A.  There is no=20
| indication whether a similar rule applies to declarations=20
| like "import A hiding (x, ...)" if x is not exported from A. =20

I propose that hiding something that isn't exported should be=20
considered an error.  It's not actually harmful but it is misleading.

| 2) The semantics of "module M" style entries in export lists seems to
| be underspecified.   Here are some programs to illustrate:
|=20
|    Program 1:  module A(module B, ...) where
|    ~~~~~~~~~~   ... code that doesn't import B ...
|=20
|    Is this valid?  We thought that it should probably be invalid,
|    but could also see an interpretation in which it was valid, but
|    with nothing exported for the "module B" part.

By the same token, I think this should be an error.

|    Program 2:  module A(module B, ...) where
|    ~~~~~~~~~~   import qualified B
|                 ... code that doesn't import B ...
|=20
|    A similar example: now B appears as an import, but there are no
|    unqualified imports of B, so either "module B" adds nothing to the
|    export list (except instances?), or else this program is an error.
|=20
|    Item 5 on p65 (describing entities exported from modules) says that
|    "module m" exports entities brought into scope from m by one or
more
|    *unqualified* imports.  But this example suggests more; that it
will
|    export instances brought into scope from *qualified* imports too.
|    Perhaps the intention is that "module m" exports all instances,
|    and all entities that are imported from m with an unqualified name?

I don't think it should matter whether B is imported qualified or not; I
propose
to remove the *unqualified* adjective in the above quote.

The export list specifies what is exported, and can include qualified
names:
	module A( B.f ) where
	import qualified B

So 'module B' in an export list means "everything imported from B"
regardless of
whether the things imported from B are known by a qualified or
unqualified name.

|    Program 3:  module A(module B, ...) where
|    ~~~~~~~~~~   import B as C
|                 ... code that doesn't import again from (or as) B ...
|=20
|    Program 4:  module A(module B, ...) where
|    ~~~~~~~~~~   import C as B
|                 ... code that doesn't import again from (or as) B ...
|=20
|    Which of these is valid?  Does the "B" in "module B" refer to the
|    literal name of the module from which entities are imported, the
|    local alias by which they are referenced, ... or both? =20

Good question!   Given
	import X as Y
module X is known as Y throughout the importing module, so [proposal] I=20
think it should be module Y that appears in the export list, not X.

So a good summary of what is exported by "module Y" would be "every
entity
e for which Y.e is in scope".    [Recall that everything is always
imported qualified,=20
and perhaps unqualified too.]


Simon