It seems like there is no easy way to prevent D's import statements from clouding the global namespace:
module x;
import std.stdio;
void main() {
writeln("Hello!");
}
As soon as you import std.stdio
, writeln
is now global. Coming from [language with namespaces]
, it would be nice if I could only reference std.stdio.writeln
, especially so in a week or two I can easily tell what provides writeln
.
After reading Namespaces with classes and structs?, it seems to me that this should do what I'd like (as unwieldly as it is):
module x;
import std.stdio;
class String {
struct write {
auto println = writeln;
}
}
void main() {
String string = new String();
string.write.println("Hello!");
}
But I get Error: variable [...] type void is inferred from initialiser [...], and variables cannot be of type void
, which means function aliasing is out.
Were I writing C, I could understand the lack of namespaces (but I could still achieve them with structs and dot-notation). Is there any way to get imported names to not be so global?
I'm inclined to agree with @weltensturm -- D handles conflicts gracefully, and artificially creating namespaces is only likely to confuse things.
One of the nice parts of D (IMHO) is avoiding those long names you see in other languages without worrying that something terrible will happen.
However, if you really need to, take a look at the docs on modules, which show how you can rename a module:
import io = std.stdio;
void main()
{
io.writeln("hello!"); // ok, calls std.stdio.writeln
std.stdio.writeln("hello!"); // error, std is undefined
writeln("hello!"); // error, writeln is undefined
}
You can also use a static import so you are forced to use the fully qualified name:
static import std.stdio;
void main()
{
std.stdio.writeln("hello!"); // OK
writeln("hello!"); // error, writeln is undefined
}