[Haskell-cafe] Proposal for an extension: in-module namespaces

Robin Palotai palotai.robin at gmail.com
Tue Mar 28 07:06:03 UTC 2017


My subjective cents:

- Namespace pollution practically doesn't exist if you import qualified.

- The common stuff you always import can just go to a custom prelude. You
can roll your own based on, say, Protolude [1].

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).

Robin

[1]: http://www.stephendiehl.com/posts/protolude.html

2017-03-27 23:11 GMT+02:00 Aura Kelloniemi <kaura.dev at sange.fi>:

> Hello
>
> I've been thinking about an extension to GHC which would allow creating new
> module-like namespaces within normal Haskell modules. Because this kind of
> namespacing system seems quite obvious to me, I ask if it has already been
> proposed or discussed in detail?
>
> The motivation:
> 1. It would assist in solving the 'pollution of namespace' -problem, of
> which
> many Haskellers have complained.
>
> 2. It would allow building bundles of related modules which can be exported
> from one module and then imported into others. This could result in
> radically fewer import statements.
>
> Rant:
>
> I'm tired of writing
>
> import qualified Data.ByteSstring as B
> import qualified Data.ByteString.Builder as B
> import qualified Data.ByteString.Lazy as BL
> import qualified Data.ByteString.Lazy.Builder as BL
> import qualified Data.HashMap.Strict as HM
> import qualified Data.Text as T
> import qualified Data.Text.Lazy as TL
> import qualified Data.Text.Lazy.Builder as BL
>
> A huge portion of this appears in almos all my Haskell source files. If I
> wrote my code in Python, I could condense all these imports to:
>
>
> So, you see, it was zero lines of code.
>
> I'm also tired of these patterns:
> (personName p), (companyName c), (objectName o), ... and I hardly
> prefer (name (p :: Person)), (name (c :: Company)) or (name (o ::Object))
> using the DuplicateRecordFields syntax.
>
> Proposal:
>
> I propose that modules can contain named submodules. They can be exported
> and
> imported just like anything else within a module, like this:
>
> {-# LANGUAGE Submodules #-}
> module Library.Things
>     (qualified module Person,
>      qualified module Company,
>      personWorksInCompany
>     ) where
>
> -- import ...
>
> qualified module Person (Person (..)) where
>     -- This is the module Library.Things.Person. Submodules could possibly
>     -- use some other keywords than 'qualified module'. Maybe just
> 'module',
>     -- 'submodule' or 'namespace'.
>     data Person = Person {
>             name :: {-# UNPACK #-} !T.Text,
>             id   :: {-# UNPACK #-} !Unique,
>             ...
>             }
>
> -- Back in Library.Things
> qualified module Company where
>     data Company = Company {
>         name      :: {-# UNPACK #-} !T.Text,
>         employees :: {-# UNPACK #-} !V.Vector Unique,
>         ...
>         }
>
> -- back in Library.Things again:
>
> personWorksIn :: Person.Person -> Company.Company -> Bool
> personWorksIn p c = Person.id p `elem` Company.employees c
>
> -- ... end of Library.Things
>
> And in another file:
>
> {-# LANGUAGE Submodules #-}
>
> -- The following demonstrates some ways of importing submodules. They are
> -- not meant to be used like this in real code:
> import Library.Things
> import qualified Library.Things as Things
>
> -- Now the submodules are also in scope and can be referred to like this:
> person1 :: Person.Person
> person2 :: Things.Person.Person
> company :: Library.Things.Company.Company
>
> -- And we also could have written: after importing Library.Things:
> import Person
> -- And now data type Person, selector name, etc. are in scope
> -- If we also imported the Company module:
> import Things.Company
> -- selector 'name' would now be ambiguous and need qualification at use
> site.
>
> -- Import lists would also work when bringing submodule contents to current
> -- namespace. Like this:
> import Library.Things hiding (module Company)
> -- or
> import qualified Library.Things (module Person)
> -- Which would allow Library.THings.Person.Person to be used requiring use
> of
> -- the fully qualified name.
>
> -- But the following would not work if Library.Things was not already
> -- imported:
> import Library.Things.Person
> -- because there is no such module, just submodule.
>
> -- ... end of other file
>
> Some projects probably would like to create a module like this:
>
> module Imports
>     (qualified module B,
>      qualified module HM,
>      qualified module T
>     ) where
>
> import Data.ByteString as B
> -- ... and so forth ...
>
> Open questions:
>
> - Should there be a separate keyword for importing submodules, for example
>   'use' or 'import namespace'?
> - Would imports be allowed within submodules? I'd say no for importing
> other
>   modules, but importing submodules could be ok.
> - Would it be possible to extend submodules after their initial definition
>   by just writing a new 'qualified module' block? I'd say yes, because
>   submodules are just about namespacing. It is today possible to import
>   many modules qualified and put them in the same namespace, like is often
>   done.
> - What do you fellow Haskellers think about this all?
>
> --
> Aura
> _______________________________________________
> Haskell-Cafe mailing list
> To (un)subscribe, modify options or view archives go to:
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> Only members subscribed via the mailman list are allowed to post.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20170328/ce310dc4/attachment.html>


More information about the Haskell-Cafe mailing list