Thread overview
Import modules too verbose in some cases
Aug 09, 2017
Johnson Jones
Aug 10, 2017
Rene Zwanenburg
Aug 10, 2017
Adam D. Ruppe
August 09, 2017
Sometimes one doesn't want to import either the whole module nor specify a single function to import. It seems that basically D has all the info to import the function implicitly because it usually gives a nice error message tells us which module to import for the function.

e.g.,

A.B.C()

"Did you forget to import module A.B?"

and so we have to do

import A.B;
A.B.C();

Sometimes we still need to specify the fully qualified name due to conflicts with other modules.


Rather, how about a new feature were we do not have to import modules at all by specifying the fully qualified name? Since conflicts might occur, how bout using a symbol to express that?

#A.B.C();

or

@A.B.C();

or

$A.B.C();

same as

import A.B;
A.B.C();


So, for one offs we don't have to write the import statement.



August 10, 2017
On Wednesday, 9 August 2017 at 23:57:19 UTC, Johnson Jones wrote:
> Sometimes one doesn't want to import either the whole module nor specify a single function to import. It seems that basically D has all the info to import the function implicitly because it usually gives a nice error message tells us which module to import for the function.

It doesn't have that information available, and that's unlikely to change due to the compilation model. Rather, a few very common cases have been hardcoded in the compiler:

https://github.com/dlang/dmd/blob/4d86fcba2fd2ef86cc85738cd2ac2b059dbb5800/src/ddmd/imphint.d
August 10, 2017
On Wednesday, 9 August 2017 at 23:57:19 UTC, Johnson Jones wrote:
> Sometimes one doesn't want to import either the whole module nor specify a single function to import.

There was a proposal called "dependency carrying declarations" about that, but a library trick was found to beat it:

https://github.com/dlang/druntime/pull/1756

They called it "self-important lookups"...though the PR was never actually merged, but as you can see in there, the code was actually quite trivial (the PR is about 95% documentation):

template from(string moduleName)
{
    mixin("import from = " ~ moduleName ~ ";");
}


So then you can do an inline import and reference right there.

> It seems that basically D has all the info to import the function implicitly because it usually gives a nice error message tells us which module to import for the function.

It is guessing there, giving a hint to users but it doesn't actually have enough information to fix it automatically. Consider:

struct A {
  static struct B {
      static void C() {}
  }
}

in that case A.B.C() is the struct function, not an import. The line between the package+module and the inner symbol is unknown without an import.

> Sometimes we still need to specify the fully qualified name due to conflicts with other modules.

Keep in mind too that you can do renamed imports:

import short = some.long.name;

short.foo(); // refers to some.long.name.foo();

> Rather, how about a new feature were we do not have to import modules at all by specifying the fully qualified name? Since conflicts might occur, how bout using a symbol to express that?
>
> #A.B.C();


This is what the `from!"A.B".C()` trick linked above enables. But notice that the module is in quotes - it still doesn't know where where the line is drawn between module and inner name without you telling it somehow.