www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Function-local imports

reply bearophile <bearophileHUGS lycos.com> writes:
In some situations I'd like to import names inside a function, as sometimes
done in Python:

int foo(int x) {
    import std.math: sqrt;
    return cast(int)(sqrt(cast(real)x) * 2);
}


Keeping the import closer to the scope where the name (here sqrt) is used is
useful because it keeps the global namespace of the module cleaner. Global
names are better minimized.

Importing global names like this can be problematic because later in the module
it can be hard to remember where the bar and baz names come from:

from foo import bar, baz;

To avoid this problem you can use:
static import foo;
so later you have to use:
foo.bar
that is states its origin clearly.

Keeping imports closer to the point where the imported names are used lowers
the risk of confusing it with something else, while allowing nonstatic imports.

Imports local in a function can be useful in unit tests too, because the can
require modules normally not used (for example std.stdio) by the module.
version(unittest){...} can be used for a similar purpose.

One disadvantage of function-local imports is that looking at the header of a
module you can't tell all the modules it imports, you have to perform a search
in the whole module. But this is true for global-level imports too, that can be
scattered in the whole module (but they usually aren't). So function-local
imports have to be used with care.

Bye,
bearophile
Apr 25 2010
parent reply Jesse Phillips <jessekphillips+D gmail.com> writes:
bearophile wrote:

 In some situations I'd like to import names inside a function, as sometimes
done in Python:

 int foo(int x) {
     import std.math: sqrt;
     return cast(int)(sqrt(cast(real)x) * 2);
 }

Can't you just use 'with'? static import std.math; // Code... int foo(int x) { with(std.math) { return cast(int)(sqrt(cast(real)x) * 2); } } Or was there another issue trying to be solved?
Apr 25 2010
parent reply retard <re tard.com.invalid> writes:
Mon, 26 Apr 2010 04:40:09 +0000, Jesse Phillips wrote:

 bearophile wrote:
 
 In some situations I'd like to import names inside a function, as
 sometimes done in Python:

 int foo(int x) {
     import std.math: sqrt;
     return cast(int)(sqrt(cast(real)x) * 2);
 }

Can't you just use 'with'? static import std.math; // Code... int foo(int x) { with(std.math) { return cast(int)(sqrt(cast(real)x) * 2); } } Or was there another issue trying to be solved?

The other thing is to disable the visibility of the symbol outside the with scope. There are languages that have succesfully unified these two constructs. D isn't one of them.
Apr 26 2010
parent Jesse Phillips <jessekphillips+D gmail.com> writes:
retard Wrote:

 
 Can't you just use 'with'?
 
 static import std.math;
 
 // Code...
 
 int foo(int x) {
     with(std.math) {
        return cast(int)(sqrt(cast(real)x) * 2);
     }
 }
 
 Or was there another issue trying to be solved?

The other thing is to disable the visibility of the symbol outside the with scope. There are languages that have succesfully unified these two constructs. D isn't one of them.

I guess I don't understand why that is of value.
Apr 27 2010