<div dir="ltr"><div><div><div><div>My subjective cents:<br><br></div>- Namespace pollution practically doesn't exist if you import qualified.<br><br></div>- The common stuff you always import can just go to a custom prelude. You can roll your own based on, say, Protolude [1].<br><br></div>Please weight a power-to-disturbance ratio of new features. Each of these become additional burden when learning or for tool writers (say automatic refactoring tools etc).<br><br></div>Robin <br><br>[1]: <a href="http://www.stephendiehl.com/posts/protolude.html">http://www.stephendiehl.com/posts/protolude.html</a><br></div><div class="gmail_extra"><br><div class="gmail_quote">2017-03-27 23:11 GMT+02:00 Aura Kelloniemi <span dir="ltr"><<a href="mailto:kaura.dev@sange.fi" target="_blank">kaura.dev@sange.fi</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hello<br>
<br>
I've been thinking about an extension to GHC which would allow creating new<br>
module-like namespaces within normal Haskell modules. Because this kind of<br>
namespacing system seems quite obvious to me, I ask if it has already been<br>
proposed or discussed in detail?<br>
<br>
The motivation:<br>
1. It would assist in solving the 'pollution of namespace' -problem, of which<br>
many Haskellers have complained.<br>
<br>
2. It would allow building bundles of related modules which can be exported<br>
from one module and then imported into others. This could result in<br>
radically fewer import statements.<br>
<br>
Rant:<br>
<br>
I'm tired of writing<br>
<br>
import qualified Data.ByteSstring as B<br>
import qualified Data.ByteString.Builder as B<br>
import qualified Data.ByteString.Lazy as BL<br>
import qualified Data.ByteString.Lazy.Builder as BL<br>
import qualified Data.HashMap.Strict as HM<br>
import qualified Data.Text as T<br>
import qualified Data.Text.Lazy as TL<br>
import qualified Data.Text.Lazy.Builder as BL<br>
<br>
A huge portion of this appears in almos all my Haskell source files. If I<br>
wrote my code in Python, I could condense all these imports to:<br>
<br>
<br>
So, you see, it was zero lines of code.<br>
<br>
I'm also tired of these patterns:<br>
(personName p), (companyName c), (objectName o), ... and I hardly<br>
prefer (name (p :: Person)), (name (c :: Company)) or (name (o ::Object))<br>
using the DuplicateRecordFields syntax.<br>
<br>
Proposal:<br>
<br>
I propose that modules can contain named submodules. They can be exported and<br>
imported just like anything else within a module, like this:<br>
<br>
{-# LANGUAGE Submodules #-}<br>
module Library.Things<br>
    (qualified module Person,<br>
     qualified module Company,<br>
     personWorksInCompany<br>
    ) where<br>
<br>
-- import ...<br>
<br>
qualified module Person (Person (..)) where<br>
    -- This is the module Library.Things.Person. Submodules could possibly<br>
    -- use some other keywords than 'qualified module'. Maybe just 'module',<br>
    -- 'submodule' or 'namespace'.<br>
    data Person = Person {<br>
            name :: {-# UNPACK #-} !T.Text,<br>
            id   :: {-# UNPACK #-} !Unique,<br>
            ...<br>
            }<br>
<br>
-- Back in Library.Things<br>
qualified module Company where<br>
    data Company = Company {<br>
        name      :: {-# UNPACK #-} !T.Text,<br>
        employees :: {-# UNPACK #-} !V.Vector Unique,<br>
        ...<br>
        }<br>
<br>
-- back in Library.Things again:<br>
<br>
personWorksIn :: Person.Person -> Company.Company -> Bool<br>
personWorksIn p c = Person.id p `elem` Company.employees c<br>
<br>
-- ... end of Library.Things<br>
<br>
And in another file:<br>
<br>
{-# LANGUAGE Submodules #-}<br>
<br>
-- The following demonstrates some ways of importing submodules. They are<br>
-- not meant to be used like this in real code:<br>
import Library.Things<br>
import qualified Library.Things as Things<br>
<br>
-- Now the submodules are also in scope and can be referred to like this:<br>
person1 :: Person.Person<br>
person2 :: Things.Person.Person<br>
company :: Library.Things.Company.Company<br>
<br>
-- And we also could have written: after importing Library.Things:<br>
import Person<br>
-- And now data type Person, selector name, etc. are in scope<br>
-- If we also imported the Company module:<br>
import Things.Company<br>
-- selector 'name' would now be ambiguous and need qualification at use site.<br>
<br>
-- Import lists would also work when bringing submodule contents to current<br>
-- namespace. Like this:<br>
import Library.Things hiding (module Company)<br>
-- or<br>
import qualified Library.Things (module Person)<br>
-- Which would allow Library.THings.Person.Person to be used requiring use of<br>
-- the fully qualified name.<br>
<br>
-- But the following would not work if Library.Things was not already<br>
-- imported:<br>
import Library.Things.Person<br>
-- because there is no such module, just submodule.<br>
<br>
-- ... end of other file<br>
<br>
Some projects probably would like to create a module like this:<br>
<br>
module Imports<br>
    (qualified module B,<br>
     qualified module HM,<br>
     qualified module T<br>
    ) where<br>
<br>
import Data.ByteString as B<br>
-- ... and so forth ...<br>
<br>
Open questions:<br>
<br>
- Should there be a separate keyword for importing submodules, for example<br>
  'use' or 'import namespace'?<br>
- Would imports be allowed within submodules? I'd say no for importing other<br>
  modules, but importing submodules could be ok.<br>
- Would it be possible to extend submodules after their initial definition<br>
  by just writing a new 'qualified module' block? I'd say yes, because<br>
  submodules are just about namespacing. It is today possible to import<br>
  many modules qualified and put them in the same namespace, like is often<br>
  done.<br>
- What do you fellow Haskellers think about this all?<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
Aura<br>
______________________________<wbr>_________________<br>
Haskell-Cafe mailing list<br>
To (un)subscribe, modify options or view archives go to:<br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-<wbr>bin/mailman/listinfo/haskell-<wbr>cafe</a><br>
Only members subscribed via the mailman list are allowed to post.</font></span></blockquote></div><br></div>