Changes between Initial Version and Version 1 of Records/NestedModules

Jan 21, 2012 11:10:39 PM (3 years ago)

Pasted from emails. Needs editing.


  • Records/NestedModules

    v1 v1  
     1Proposal for A: 
     3Allow nested modules. A nested module can occur in any 
     4position that a data declaration can occur. The syntax of 
     5a nested module is the same as the syntax of a conventional 
     8A nested module must have the same hierarchical name as 
     9the module in which it is nested, followed by a single additional 
     10component. A name with a single component can be specified 
     11in the declaration of a nested module; this is syntactic sugar for 
     12the fully qualified name of the enclosing module followed by that 
     13single additional component. 
     15When a module M.A is directly nested in module M, there is 
     16an implied import in the enclosing module M as follows: 
     18import qualified M.A as A 
     20and an implied import in the nested module M.A as follows: 
     22import M 
     24These implied imports may optionally be specified explicitly 
     25with no effect, or overridden with other explicit imports, 
     26similarly to the usual implied import of Prelude. 
     28When modules are nested to a depth greater than one, 
     29similar implied imports exist for all recursively enclosing 
     30and enclosed modules, with the same rules about 
     33If an enclosing module M has an export list, a nested 
     34module N at any depth recursively cannot be imported 
     35by modules not nested inside M unless N is included in 
     36the export list of M. If M does not have an export list, 
     37N can be imported by any other module as usual. 
     39In every other respect, a nested module declaration has 
     40exactly the same effect as any other module declaration. 
     41In particular, the behavior of nested modules in the 
     42presence of all corner cases such as data families, etc., 
     43is specified by this rule. 
     45The effect of a nested module on the behavior of 
     46ghc --make is left unspecified as of now, until 
     47there is feedback from the GHC team. This would 
     48probably involve GHC looking for A.B and then 
     49A in turn when it fails to find A.B.C. Or perhaps 
     50even when A.B.C is found, to identify erroneous 
     51duplication. Or GHC could stay pretty much as 
     52it is now, relying on the user to ensure that GHC 
     53finds the nested module; that would certainly 
     54be fine for an initial implementation. 
     57Usage example: 
     59module Library where 
     60 import Data.Text (Text) 
     62 type ISBN = Text 
     63 module Book where 
     64   import Data.Text (Text) 
     65   data T = New { name :: Text, iSBN :: ISBN } 
     66 module Checkout where 
     67   import Data.Time 
     68   import qualified Library.Book as Book 
     69   import qualified Library.Borrower as Borrower 
     70   data T = New 
     71     { book :: Book.T, borrower :: Borrower.T, dueDate :: Day } 
     72 module Borrower where 
     73   import Data.Text (Text) 
     74   data T = New { name :: Text, address :: Text } 
     75 module History where 
     76   import qualified Library.Borrower as Borrower 
     77   import qualified Library.Checkout as Checkout 
     78   data T = New { borrower :: Borrower.T, checkouts :: [Checkout.T] } 
     80This makes available in the module Library the 
     81record types: 
     83Book.T, Checkout.T, Borrower.T, History.T 
     85with constructors: 
     87Book.New, Checkout.New, Borrower.New, History.New 
     89and record accessors: 
     90, Book.iSBN,, Checkout.borrower, Checkout.dueDate,, Borrower.address, 
     94History.borrower, History.checkouts 
     96I believe this specification should be very simple to 
     97implement and describe. There are some obvious 
     98shortcomings. But it does provide basic namespacing 
     99of records with almost no change to Haskell and GHC. 
     101Note also that you need to be careful to avoid mutually 
     102recursive imports. That is really more of a limitation 
     103of GHC than a limitation of the specification itself. 
     104Other compilers might not require that. 
     106I'd be happy to hear ideas about how to develop this 
     107simple idea further and eliminate some of the 
     108shortcomings, on condition that it doesn't lead to 
     109further bikeshedding and significant delay. 
     111One obvious enhancement would be for the 
     112implied import of the enclosing module to 
     113include also all names imported into 
     114the enclosing module, unlike the usual 
     115convention for imports. I'm not sure if 
     116there are complications to that though. 
     120Whenever any module E imports M unqualified without an 
     121import list, as in: 
     123import M 
     125then the following implied imports would be added to E: 
     127import qualified M.T as T 
     128import qualified M.S as S 
     130and whenever E imports M qualified without an 
     131import list, as in: 
     133import qualified M as Q 
     135then the following implied imports would be 
     136added to E: 
     138import qualified M.T as Q.T 
     139import qualified M.S as Q.S 
     141Similarly, if M also contains more deeply nested 
     142modules and E imports M either qualified or 
     143unqualified without an import list, the corresponding 
     144implied imports of the deeply nested modules would 
     145also be added to E. But in fact, this is nothing 
     146more than a recursive application of the previous 
     149Note that an import statement with an import list 
     150will never generate any automatic import of 
     151a nested module.