[Issue 13855] Allow multiple selective imports from different modules in a single import statement

d-bugmail at puremagic.com d-bugmail at puremagic.com
Fri Dec 22 19:23:38 UTC 2017


https://issues.dlang.org/show_bug.cgi?id=13855

hsteoh at quickfur.ath.cx changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |hsteoh at quickfur.ath.cx

--- Comment #8 from hsteoh at quickfur.ath.cx ---
In light of the recent move towards local imports vs. global imports, I'm
starting to think that what we *really* want is for the compiler to *automate*
imports for us.

It's analogous to the old days with (early versions of) C, where you have to
declare all local variables at the top of the function.  C++ improved on this
by allowing variable declarations closer to where they're actually used (I'm
not sure if this is standard C, but recent implementations like gcc seem to
have also adopted this in C code). This is like moving imports from module
scope to local scope.

However, C++ (well, earlier versions of it) still suffered from having to type
incredibly long type names, like:

------
std::vector<int>::iterator it = std::vector<int>::iterator::end;
------

D improved upon this by allowing the LHS type name to be elided where the type
can be inferred by the compiler.  Most of the time, this is possible, so in
modern idiomatic D code these days, using `auto x = ...` is commonplace and
greatly improves legibility.

What if we had an analogous "import inference", where you don't need to spell
out long complicated module names just to be able to use some symbol in some
module std.abc.xyz?  Let the compiler figure it out for us.

This is still a raw initial idea, so it will need further refinement, but my
thought is something along these lines:  suppose we introduced a "lazy import"
construct:

------
auto myFunc(Args...)(Args args) {
    lazy import std.algorithm;
    return args.map!(x => x*2).filter!(x < 100);
}
------

The lazy import tells the compiler that if undefined symbols are encountered,
it should look into std.algorithm to see if the symbol is defined there. If it
is, implicitly import the module that it's defined in, and keep going. 
Otherwise emit an error message.

If there is any ambiguity that arises, e.g., both std.algorithm.foo.bar and
std.algorithm.baz.bar exist, and `bar` is referred to, then also emit an error,
and require disambiguation using the usual mechanisms (e.g., naming `foo.bar`
or `baz.bar`).

If a recent proposal for `import std;` gets accepted, then we could even have:

------
lazy import std; // I'm lazy, just lookup all symbols in Phobos for me
... // use std.*.* to your heart's content
------

This could be placed either in module scope or in local scope, depending on
just how lazy you are.  It kills all boilerplate and verbosity by reducing
import statements to their bare minimum.

--


More information about the Digitalmars-d-bugs mailing list