June 10, 2018
Suppose you have a large source file. You use functions from outside libraries that use other components not directly in their own library:

module X
import Foo : foo;
auto x = foo();


module Foo;
import F : I;
I foo();


module F;
interface I;
class f : I;
alias Q = I;
f bar(f);

now, remember that Foo.foo returns an F.f in X. Auto saves the day because we don't have to explicitly state the type. This allows us to avoid importing F.

But suppose we want to cast the return value to f even though it's an I.

auto x = cast(f)foo();


Now we have to import the module F! auto does save us any more.


What the compiler should do is notice that it can implicitly import f. Why? Because it could implicitly import I and there is no ambiguity.

Notice that there is absolutely no difference in the analysis by the compile between these two:

auto x = foo();
auto x = cast(Q)foo();  // Note that the module of foo is known, and so Q can be deduced. That is, If no Q exists in the current scope then try the module of foo's return type(f), if not found try foo's module(F).


But with the explicit cast we have to import Q. But don't you think that once the compiler knows the module it can just chain it along as if it were imported explicitly?


auto x = foo();
x.bar(x);  // bar is known because x is from module F and bar is also from F. It is "implicitly" imported. If bar already exists in the imports then an error is given. The user an use an alias to get around the problem as usual.


This feature will allow one to avoid having to import modules explicitly when the compiler can easily deduce the modules without ambiguity.





June 10, 2018
another interesting syntax:

import [] : std.algorithm, std.math;

Does implicit importing on all arrays.

int[] x;

x.canFind(x[0]);   // does implicit import for canFind!


At some point we might even be able to get away from 90% of importing.