GHC Proposal: ImplicitQualifiedImport

Greeting, here is a proposal to enable implicit qualified import:

Please, speak out there if you have an opinion on this.

Kind Regards,
-Tristan

3 Likes

Thanks for sharing. I will give you my comment:

  • I guess as today I find it useful to look at the “header” of an .hs file (its import list) as a “reference of modules/functions you should know before diving in the code”. If I understand correctly, this proposal would break this (minor) advantage.
  • What would happen with smart editors, etc.? I am pretty sure at least one has “show signature on hover”; would the cope with this?
  • In general how complex is to implement and especially to maintain this?
2 Likes
  • That is correct, the module header would no longer be enough to learn about its dependencies. That is listed as the first drawback of the proposal.
  • I think smart editors already know about all the available qualified modules, and I assume it should be relatively simple to make them use the new extension.
  • Since the feature already exists for GHCi, the change to GHC should be fairly limited. Though I’m looking forward feedback to double check the proposed specification :slight_smile:

Thanks!

1 Like
  1. Will this change negatively impact compiler performance, especially when template haskell is involved?
  2. How does it handle cycles?

@gilmi

  1. The extension adds an overhead when resolving the modules dependencies because we need to look for implicit imports usage anywhere in the module. Though that should not affect template haskell.
  2. The extension should use the existing import mechanisms so that cycles are handled as usual.
1 Like

I find explicit imports super useful and helpful, particularly when learning Haskell, and even as an experienced Haskeller, learning about code that is new to us.

This extension may improve the language’s learnability for novice users by

When I started using Haskell, I found the opposite to be true: Even with the form of implicit imports we have today, I would very often ask myself “where does X (function/datatype) come from?” So I don’t see how reducing those imports improves the language’s learnability.

Haskell is already very concise and to the point, even as a Haskeller with some experience, I don’t see imports as a nuisance, I generally find great value in those import statements. For code we are unfamiliar with, explicit imports tell us where those bits came from and where to look for more info about those things. Coming from the perspective that “code is much more often read than written”, I don’t see any value in being able to skip these imports as an author, and I would see that as a detriment for people reading the code later.

In my own code, I go as far as being explicit about each function/datatype/etc I am using, and I try to avoid the implicit import Foo (from the code I’ve read, I’d say most experienced haskellers don’t do this, but as a new haskeller I found that type of code harder to read and learn). I think code modules lacking any of that would be less enjoyable and not as easy to read and discover.

I would also ask: how does an ImplicitQualifiedImport discern the author’s intention when there are overlapping names of function/datatype across several modules/packages?

4 Likes

The extension only works for fully qualified names, such as System.Environment.getArgs, thus the reader should always be able to know where the name is defined. I’m not sure to understand what is the concern about readability or overlapping names.

I think this has the potential to improve learnability because novice user would be able to use module without having to learn how import works. How to use import statement could be introduced later, for example to avoid repetition.

2 Likes

Thanks for the clarification, I overlooked that, but understand what you mean now.

I can understand the reasoning, though I am of the opinion that imports should be taught sooner/earlier - at least in my own experience learning this stuff, having a more solid understanding of imports and the nuances there made my other learning easier and more enjoyable. I say the same about the topics related to language pragmas, packages, hackage/stackage, and building haskell software in general. Putting that off to later ends up leading to more frustration that is necessary, whereas getting a good understanding early makes it easier to discover and learn the language.

So, are people aware of -fimplicit-import-qualified? It’s somewhat hard to find since the option is not in the master option index and it’s a -f instead of a language extension as one might expect. It’s documented here, and last time I checked it did work in compiled programs as well as in ghci.

@geekosaur The proposal deprecates the -fimplicit-import-qualified flag in favor of the -XImplicitQualifiedImport extension because this changes how to interpret the source file. Also it seems like the flag only works in the context of GHCi.

That flag doesn’t seem to work when loading source files:

$ cat Main.hs
main = System.IO.print ()
$ ghc -fimplicit-import-qualified Main.hs
[1 of 1] Compiling Main             ( Main.hs, Main.o )

Main.hs:1:8: error:
    Not in scope: ‘System.IO.print’
    No module named ‘System.IO’ is imported.
  |
1 | main = System.IO.print ()
  |        ^^^^^^^^^^^^^^^
$ echo :quit | ghci -fimplicit-import-qualified Main.hs
GHCi, version 9.2.2: https://www.haskell.org/ghc/  :? for help
Loaded GHCi configuration from /Users/taylor/.ghci
[1 of 1] Compiling Main             ( Main.hs, interpreted )

Main.hs:1:8: error:
    Not in scope: ‘System.IO.print’
    No module named ‘System.IO’ is imported.
  |
1 | main = System.IO.print ()
  |        ^^^^^^^^^^^^^^^
Failed, no modules loaded.
>>> Leaving GHCi.
$ echo 'System.IO.print ()' | ghci
GHCi, version 9.2.2: https://www.haskell.org/ghc/  :? for help
Loaded GHCi configuration from /Users/taylor/.ghci
>>> ()
>>> Leaving GHCi.

I wonder when that changed. I know I tested it and found it to work, but I don’t recall when and it may have been back in the 6.6 days.

I think there should be a corresponding warning flag to warn when multiple values from the same module are imported implicitly, as this would usually be better done by explicitly specifying the module to import from.