# Namespaces, imports, plugins

**URL:** <https://discourse.haskell.org/t/namespaces-imports-plugins/9143>\
**Category:** Uncategorized\
**Created:** [March 23, 2024, 3:24am UTC](https://discourse.haskell.org/t/namespaces-imports-plugins/9143 "2024-03-23T03:24:04Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![mikeplus64](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/mikeplus64/32/3998_2.png) [@mikeplus64](https://discourse.haskell.org/u/mikeplus64)\
**Post date:** [March 23, 2024, 3:24am UTC](https://discourse.haskell.org/t/namespaces-imports-plugins/9143/1 "2024-03-23T03:24:04Z")

</div>

This is gonna be a somewhat rambling request for comment/ideas about imports in Haskell. It’s spurred by [Announcing Imp, a GHC plugin for automatically importing modules - #16 by atravers](http://discourse.haskell.org/t/announcing-imp-a-ghc-plugin-for-automatically-importing-modules/9140/17) but is something I’ve thought about for a while.

I have been wondering about for a while is if an import plugin introducing a new `import` syntax, with the following features, would be possible:

- Allow importing in a hierarchy a la Rust
- Reduce the syntax needed to do the “type and qualified module” idiom that people (or at least, me) often use, like importing the type `Vector` and qualified importing all of `Data.Vector` under `Vector` name as well.
- Support renaming
- Explicit namespaces only

What I’d like is something like:

```haskell
use Data.Text (type Text, module as Text, module Encoding as Text)

-- with renaming
use Data.Text.Lazy (type Text as LText, module as LText, module Encoding as LText)

```

to mean

```haskell
import qualified Data.Text as Text
import qualified Data.Text.Encoding as Text
import Data.Text (Text)

-- renaming
import qualified Data.Text as LText
import qualified Data.Text.Encoding as LText
import qualified Data.Text.Lazy
-- something like `type LText = Data.Text.Lazy.Text`, except done by the renamer

```

It would not support unqualified-`as` imports at all - I just think that those are a mistake. I looked at GHC plugins briefly and it seems like extending what syntax `import` allows wouldn’t be possible, hence `use`. Can a renamer plugin do the renaming part? Is it possible at all?

There’s a few things disheartening me though: (1) required time and effort 🙂 (2) that the entire Haskell module system just doesn’t work that well, and such a plugin as above would be just papering over that fact, but then actually changing it is fairly unfathomable. I sometimes wish we had “default”/“index” modules in directory hierarchies, inline-defined modules, module exports / “qualified exports” like `Data.Text` exports a namespace/module called `Encoding` which, i.e. `Data.Text.Encoding`.

---

<div class="post-metadata">

**Author:** ![atravers](https://avatars.discourse-cdn.com/v4/letter/a/45deac/32.png) [@atravers](https://discourse.haskell.org/u/atravers)\
**Post date:** [March 23, 2024, 5:45am UTC](https://discourse.haskell.org/t/namespaces-imports-plugins/9143/2 "2024-03-23T05:45:39Z")

</div>

> [@mikeplus64](#):
>
> (1) required time and effort

…I hear you! There are some things I would like to work on, if it weren’t for some thoroughly-frustrating _“normal space”_ matters.

> (2) that the entire Haskell module system just doesn’t work that well

…perhaps the best way to think about the current module system is as an _“exercise in minimalism”_:

> [@](#):
>
> (page 11 of 12)
> 
> The Haskell module system aims at simplicity and has a clear goal—to manage name uses in a program. Its design has largely been driven by practical concerns, which has both positive and negative consequences.
> 
> [A Formal Speciﬁcation of the Haskell 98 Module System](https://web.cecs.pdx.edu/~mpj/pubs/hsmods.pdf) (2002)

…and back in 2002, import lists probably were _much_ shorter. So the current problems could simply be due to a matter of scale - Haskell programs are now larger, which usually means more modules and thus longer import lists in each module.

But others (who I want to think are) smarter then me have also contemplated alternative module systems for similar languages e.g. see page 107 of 210 in [Functions, Frames and Interactions](https://macau.uni-kiel.de/servlets/MCRFileNodeServlet/macau_derivate_00002884/1998_tr04.pdf) (1998).

* * *

> [@mikeplus64](#):
>
> […] an import plugin introducing a new `import` syntax, with the following features, would be possible: […]

- if it isn’t…_end of story_.

- if it can be done…others may contemplate their own import plugins to enable imports in the style of e.g. Miranda(R), Erlang or perhaps even Standard ML! Now imagine **you** have the oh-so-wonderful job of trying to make libraries that each use a different style/plugin to all work together in some new program…

---

<div class="post-metadata">

**Author:** ![tomjaguarpaw](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/tomjaguarpaw/32/1230_2.png) [@tomjaguarpaw](https://discourse.haskell.org/u/tomjaguarpaw)\
**Post date:** [March 23, 2024, 8:47am UTC](https://discourse.haskell.org/t/namespaces-imports-plugins/9143/3 "2024-03-23T08:47:48Z")

</div>

I would like the ability to treat modules and the identifiers they export (and indeed packages) as first class entities. Anything short of that is just papering over the cracks.

---

<div class="post-metadata">

**Author:** ![atravers](https://avatars.discourse-cdn.com/v4/letter/a/45deac/32.png) [@atravers](https://discourse.haskell.org/u/atravers)\
**Post date:** [March 23, 2024, 9:31am UTC](https://discourse.haskell.org/t/namespaces-imports-plugins/9143/4 "2024-03-23T09:31:16Z")

</div>

See page 171 of 210 in _Functions, Frames and Interactions_.

---

<div class="post-metadata">

**Author:** ![adamgundry](https://avatars.discourse-cdn.com/v4/letter/a/34f0e0/32.png) [@adamgundry](https://discourse.haskell.org/u/adamgundry)\
**Post date:** [March 26, 2024, 8:05am UTC](https://discourse.haskell.org/t/namespaces-imports-plugins/9143/5 "2024-03-26T08:05:51Z")

</div>

> [@mikeplus64](#):
>
> I looked at GHC plugins briefly and it seems like extending what syntax `import` allows wouldn’t be possible, hence `use`. Can a renamer plugin do the renaming part? Is it possible at all?

As a prototype, perhaps a pre-processor might be the way to go? Assuming you are merely introducing new syntax that can be translated into the old syntax, then a pre-processor could implement the translation and integrate fairly nicely into GHC with the `-F` and `-pgmF` options ([5.11. Options related to a particular phase — Glasgow Haskell Compiler 9.8.1 User's Guide](https://downloads.haskell.org/ghc/9.8.1/docs/users_guide/phases.html#options-affecting-a-haskell-pre-processor)).

Of course, using a pre-processor (alone) can pretty much only fiddle with syntax. And at this point it isn’t clear that merely tweaking syntax gives enough benefit to justify changing what exists already, even if what exists already is imperfect ([osa1 - Some arguments against small syntax extensions in GHC](https://osa1.net/posts/2020-01-22-no-small-syntax-extensions.html)).

Once you get beyond syntax extensions, the design space opens up rapidly, so there are many possibilities but it takes a lot of work to move forward (cf. the [Local Modules proposal](https://github.com/ghc-proposals/ghc-proposals/pull/283)).

---

<div class="post-metadata">

**Author:** ![blamario](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/blamario/32/860_2.png) [@blamario](https://discourse.haskell.org/u/blamario)\
**Post date:** [April 2, 2024, 1:16pm UTC](https://discourse.haskell.org/t/namespaces-imports-plugins/9143/6 "2024-04-02T13:16:21Z")

</div>

I like your syntax, but I probably wouldn’t use a plugin just to reduce the import boilerplate. Did you consider submitting a GHC extension proposal?

---

<div class="post-metadata">

**Author:** ![tomjaguarpaw](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/tomjaguarpaw/32/1230_2.png) [@tomjaguarpaw](https://discourse.haskell.org/u/tomjaguarpaw)\
**Post date:** [April 4, 2024, 9:31am UTC](https://discourse.haskell.org/t/namespaces-imports-plugins/9143/7 "2024-04-04T09:31:17Z")

</div>

I’d like to give a contrary suggestion. Please make it a plugin! If it’s made into a GHC extension that means that only people who use GHC 9.12 or 9.14 (or whatever GHC it lands in) onwards will be able to use it, and its evolution will be tightly coupled to the GHC release cycle. As a plugin it will be available immediately to a wide range of GHCs and it will be possible to evolve it quickly according to user feedback and needs.

---

<div class="post-metadata">

**Author:** ![mikeplus64](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/mikeplus64/32/3998_2.png) [@mikeplus64](https://discourse.haskell.org/u/mikeplus64)\
**Post date:** [April 5, 2024, 4:10am UTC](https://discourse.haskell.org/t/namespaces-imports-plugins/9143/8 "2024-04-05T04:10:18Z")

</div>

Trying to make a GHC plugin, I dunno if it’s possible. Such syntax would result in a fatal GHC parser error so a source plugin can’t meaningfully run in the first place. I think it could work with what GHC initially sees as a TH splice with syntax like `use Data.Text (type_ Text, module_ as Text)` but I’m not a fan of having to do that. But a preprocessor can surely do it and work for basically any GHC 🙂

---

<div class="post-metadata">

**Author:** ![AntC2](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/antc2/32/1872_2.png) [@AntC2](https://discourse.haskell.org/u/AntC2)\
**Post date:** [April 5, 2024, 5:32am UTC](https://discourse.haskell.org/t/namespaces-imports-plugins/9143/9 "2024-04-05T05:32:50Z")

</div>

> [@atravers](#):
>
> …perhaps the best way to think about the current module system is as an _“exercise in minimalism”_: [and quote from a 2002 paper]

My impression is back to 1990 the original Haskell designers felt they didn’t have anything innovative to say about a module system, and/or they were already biting off as much as they could chew in producing a thoroughgoing lazy functional language.

_Is_ there anything specific about a (lazy) functional language that’s different vs a generic language X featuring separate compilation and strong type-checking across modules? IOW do we need to reinvent the wheel? Even if language X’s model is a little less than the theoretical ideal from starting with a clean sheet of paper, isn’t it better to follow some de facto best practice?

Haskell does feature some funky namespacing where usage sites can omit the module qualifier (_modid_) providing it’s unambiguous, and/or imports can introduce a new _modid_, and/or import the same module with all of unqualified, original qualifier, (multiple) new _modid_s.

> [@tomjaguarpaw](#):
>
> treat modules and the identifiers they export (and indeed packages) as first class entities.

I have a nasty feeling your “first class” won’t be the same as my “first class” won’t be the same as Haskell-programmer-with-a-background-in-language-XYZ’s idea of “first class”.

> [@adamgundry](#):
>
> using a pre-processor (alone) can pretty much only …

`CPP` is pretty rubbish for Haskell [\*\*]/there have been efforts for a more Haskell-friendly version of `CPP`, but they’ve fallen away because usually Haskell modules are embedded in bigger systems not all written in Haskell, so pre-processing has to conform to the lowest common denominator.

Are modern compilation systems not able to be a bit more clever? For modules with a `.hs` suffix, use this pre-processor; for perl use that; etc?

[\*\*] Specifically, CPP is unaware of the importance of linebreaks and indenting for Haskell syntax.

---

<div class="post-metadata">

**Author:** ![atravers](https://avatars.discourse-cdn.com/v4/letter/a/45deac/32.png) [@atravers](https://discourse.haskell.org/u/atravers)\
**Post date:** [April 5, 2024, 7:18am UTC](https://discourse.haskell.org/t/namespaces-imports-plugins/9143/10 "2024-04-05T07:18:28Z")

</div>

> [@AntC2](#):
>
> _Is_ there anything specific about a (lazy) functional language that’s different vs a generic language X featuring separate compilation and strong type-checking across modules?

I’m thinking _no_ :

- There’s `-XStrict`, which doesn’t affect Haskell’s module system (that I know of).
- [Lazy Standard ML from FOLDOC](https://foldoc.org/Lazy+SML)
- [lazy sml2c from FOLDOC](https://foldoc.org/lazy+sml2c)

The early non-strict language (Chalmers) Lazy ML relies on CPP for imports (with an `#include` for each `'.t'` interface). Amanda (another such language) seems to use a CPP-inspired mechanism (instead of`#include`, there’s an `#import` for each `'.ama'` module).

The only potential difficulty for having a _“grand unified module system”_ for all programming languages would be exports:

- I don’t know of any preprocessors that support export lists,
- and a generic _“module manager”_ would need some way to mark the language-specific (or _mangled_ ) symbols corresponding to those in an export list as being available for public use.

…it would make for an interesting project.
