August 12, 2004
Suppose we have:

#   ---- module silly.d ----
#   int a();
#   int b();
#   int c();
#   int d();
#   int e();
#   int f();
#   int g();
#   int h();
#   int i();
#   int j();
#   int k();
#   int l();
#   int m();
#   int n();
#   int o();
#   int p();
#   int q();
#   int r();
#   int s();
#   int t();
#   int u();
#   int v();
#   int w();
#   int x();
#   int y();
#   int z();

You want to call silly.f(), but ideally, you'd like to do it without polluting your namespace with all those other functions. It looks like your only option is to do:

#   import silly;

but that gets you a()..z(), not just f(). So now you have name-clashes all over
the place, which in turn means that you have to fully qualify loads of stuff
just to disambiguate.

People on this thread are suggesting that:

#    // no import
#    silly.f();

be more or less equivalent to

#    import silly;
#    silly.f();

but I think it should actually me more like:

#    import silly.f; // currently not legal D
#    silly.f();

This gets you:
(1) readable, unambiguous code (since silly.f() is fully qualified)
(2) an unpolluted namespace (since you haven't also pulled in a()..z()).

This would be very, very useful.

Oh - one last thing. import statements within libraries (and I include Phobos in this) should, in general, be private imports, for a similar reason - to avoid polluting the library-importer's namespace. For instance, currently, within the std.stream source file, there is a line which reads:

#    import std.c.stdio;

I believe this should read

#    private import std.c.stdio;
#    ^^^^^^^

because I don't /want/ my namespace to be filled with all that C stdio junk, just because I'm importing std.stream. If I choose to use it, I'll import it explicitly. Ditto all other similar examples.

Arcane Jill


August 12, 2004
In article <cffk4a$25cm$1@digitaldaemon.com>, Arcane Jill says...
>
>
>Suppose we have:
>
>#   ---- module silly.d ----

[snip]
>#   import silly;
>
>but that gets you a()..z(), not just f(). So now you have name-clashes all over
>the place, which in turn means that you have to fully qualify loads of stuff
>just to disambiguate.

There's an easy workaround for this, namely to enclose the imports in structs:

# struct silly { import silly; }
# ...
# a(); // Doesn't work
# silly.a(); // Works

but some people might find this solution ugly.

Nick


August 12, 2004
I guess this was done so that a simple build tool could identify all modules involved in the compilation by very simple scanning instead of complete parsing the source. There was such a tool, it even figured out libs needed and such. It is included with undig project on dsource, unfortunately it doesn't compile any longer

-eye

Russ Lewis schrieb:
> This is a question for Walter.  I'm curious about the reason why you have to import a file before using its functions and types.  Why can't you do this:
>   int main() {
>     std.stdio.printf("Hello world!\n");
>     return 0;
>   }
> 
> I'm thinking here is that the compiler could do this:
>   * Search the current namespaces for 'std'
>   * Not finding std, look for a directory std/ or a
>     file std.d
>   * Finding std/ but not std.d, look for a directory
>     std/stdio/ or a file std/stdio.d
>   * Finding std/stdio.d, it creates an implicit
>     import, like this:
> 
>   /* implicit */ import std.stdio;
>   int main() {
>     std.stdio.printf("Hello world!\n");
>     return 0;
>   }
> 
> I'm guessing that there is some good reason for not doing this, but I'm curious what it is?
> 
August 16, 2004
In article <cfg3q0$2bp5$1@digitaldaemon.com>, Nick says...
>There's an easy workaround for this, namely to enclose the imports in structs:
>
># struct silly { import silly; }
># ...
># a(); // Doesn't work
># silly.a(); // Works
>
>but some people might find this solution ugly.

Perhaps we could have some syntax sugar for this. I could imagine an import like keyword, perhaps `` use silly; '' that would cause the compiler to scan silly.d and make its declarations available to the problem, yet would not bring them into the current namespace.


August 16, 2004
ben@0x539.de wrote:

> In article <cfg3q0$2bp5$1@digitaldaemon.com>, Nick says...
> 
>>There's an easy workaround for this, namely to enclose the imports in structs:
>>
>># struct silly { import silly; }
>># ...
>># a(); // Doesn't work
>># silly.a(); // Works
>>
>>but some people might find this solution ugly.
> 
> Perhaps we could have some syntax sugar for this. I could imagine an import like
> keyword, perhaps `` use silly; '' that would cause the compiler to scan silly.d
> and make its declarations available to the problem, yet would not bring them
> into the current namespace.

Personally, I prefer this as the default behaviour.  If I want to pull a bunch of stuff into the current namespace, I'd feel better if I could say so explicitly.

Python's approach is exactly the same as D's, in fact, except for this key distinction.

    # must access contents with "foo.bar" qualifier
    # ie "foo.bar.baz()"
    import foo.bar

    # baz is pulled from foo.bar into the current scope
    # does not create foo.bar namespace at all.
    from foo.bar import baz

    # pull everything from foo.bar into the current scope
    from foo.bar import *

 -- andy
August 16, 2004
In article <cfpini$1pgg$1@digitaldaemon.com>, Andy Friesen says...
>
>ben@0x539.de wrote:
>
>> In article <cfg3q0$2bp5$1@digitaldaemon.com>, Nick says...
>> 
>>>There's an easy workaround for this, namely to enclose the imports in structs:
>>>
>>># struct silly { import silly; }
>>># ...
>>># a(); // Doesn't work
>>># silly.a(); // Works
>>>
>>>but some people might find this solution ugly.
>> 
>> Perhaps we could have some syntax sugar for this. I could imagine an import like keyword, perhaps `` use silly; '' that would cause the compiler to scan silly.d and make its declarations available to the problem, yet would not bring them into the current namespace.
>
>Personally, I prefer this as the default behaviour.  If I want to pull a bunch of stuff into the current namespace, I'd feel better if I could say so explicitly.

Then just default yourself to use the `` use '' keyword or whatever syntax there
will be, instead of always using import ;)
I think the word import itself has the meaning of importing things into the
current namespace, so I would expect it to behave exactly as it does now. But
that does not mean that I agree that this should happen all the time.

-- Benjamin Herr


August 16, 2004
In article <cfpini$1pgg$1@digitaldaemon.com>, Andy Friesen says...
>
>Personally, I prefer this as the default behaviour.  If I want to pull a bunch of stuff into the current namespace, I'd feel better if I could say so explicitly.

I don't agree with this, at least not fully. One of the things that irritate me with C++ is having to type the "using namespace blah" even when there is absolutely no chance of a name conflict. I like the D way better, it only complains when there is reason to, and THEN you can explicitly import (through alias) the names you want.

However I do agree that writing aliases can be tiresome if there are many names in conflict. The 'with' keyword exists to deal with this. But 'with' can currently only be used locally, not in the global scope. This could perhaps be changed, though.

Example: there is a conflict between std.stream.st{in,out,err} and the C equivalents in std.c.stdio. The latter is unfortunately imported publically in std.stdio (that should also be changed IMO). This could be solved in the following way:

# import std.stream;
# import std.stdio;
#
# with(std.stream); // This doesn't currently work, but maybe it should?
#
# void main()
# {
#   with(std.stream) // This already works
#     {
#       stdout.writeLine("foo");
#     }
# }

What do you think, Walter?

Nick


August 16, 2004
In article <cfqf1m$2ej0$1@digitaldaemon.com>, Nick says...

>I don't agree with this, at least not fully. One of the things that irritate me with C++ is having to type the "using namespace blah" even when there is absolutely no chance of a name conflict. I like the D way better, it only complains when there is reason to, and THEN you can explicitly import (through alias) the names you want.

You would still have that option with the way that was already proposed, so I do not see the point in your suggestion.

>However I do agree that writing aliases can be tiresome if there are many names in conflict. The 'with' keyword exists to deal with this. But 'with' can currently only be used locally, not in the global scope. This could perhaps be changed, though.

So you basically suggest the use of the with-qualifier as a better and more flexible syntax for `` using namespace ''?

I still think that it would be easier to separate the operations of loading a module and bringing its identifiers into the current namespace.

>What do you think, Walter?

I hope you forgive me for answering despite being Walter.

- ben


August 16, 2004
In article <cfqkra$2jf1$1@digitaldaemon.com>, ben@0x593.de says...
>You would still have that option with the way that was already proposed, so I do not see the point in your suggestion.

Ok I see you are correct, I guess I misread the original suggestion. I thought he was advocating a more C++ like syntax.

>So you basically suggest the use of the with-qualifier as a better and more flexible syntax for `` using namespace ''?

Using 'with' at least would not require inventing new keywords, and it would be consistant with the way it is already used.

>I still think that it would be easier to separate the operations of loading a module and bringing its identifiers into the current namespace.

Maybe, but I do not think it is critically important.

Nick


August 16, 2004
Nick wrote:
> In article <cfpini$1pgg$1@digitaldaemon.com>, Andy Friesen says...
> 
>>Personally, I prefer this as the default behaviour.  If I want to pull a bunch of stuff into the current namespace, I'd feel better if I could say so explicitly.
> 
> I don't agree with this, at least not fully. One of the things that irritate me
> with C++ is having to type the "using namespace blah" even when there is
> absolutely no chance of a name conflict. I like the D way better, it only
> complains when there is reason to, and THEN you can explicitly import (through
> alias) the names you want.
> 
> Example: there is a conflict between std.stream.st{in,out,err} and the C
> equivalents in std.c.stdio. The latter is unfortunately imported publically in
> std.stdio (that should also be changed IMO). This could be solved in the
> following way:
> 
> # import std.stream;
> # import std.stdio;
> #
> # with(std.stream); // This doesn't currently work, but maybe it should?
> #
> # void main()
> # {
> #   with(std.stream) // This already works
> #     {
> #       stdout.writeLine("foo");
> #     }
> # }

I think this is a bad idea because the 'with' keyword has a specific meaning associated with it: "with this stuff, do this stuff".  As a statement all its own, it's just the first half of that idea.  Readers will inevitably find themselves asking "do /what/ with it?".

The Python style requires an extra keyword, but I think it's worth it. 'from' doesn't make for a very good identifier name anyway.  (function names are almost always queries or verbs; attributes are nouns)

 -- andy
1 2
Next ›   Last »