On Wed, 04 Apr 2012 20:50:49 -0400, Michel Fortin <michel.for...@michelf.com> wrote:

On 2012-04-04 19:48:32 +0000, "Steven Schveighoffer" <schvei...@yahoo.com> said:

On Wed, 04 Apr 2012 14:03:07 -0400, Timon Gehr <timon.g...@gmx.ch> wrote:

No symbol is resolved until semantic, but I don't think hiding the module/package symbol if any clashing symbol in the module/any subpackage exists is a satisfactory solution.
Then we must come up with a way to hide the submodules of a virtual module.
 I tried this, which fails on the current compiler:
 import x;
 int x;
 So it seems we have two choices here:
1. DIP16 needs to get more complex to make package submodules not accesible as individual modules. 2. Start contextually interpreting identifiers at least in the case of modules vs. non-modules. I'd suggest option 2 allows for better backwards compatibility and more flexibility.

I don't think option 2 is realistic (see my other post).

I saw your other post. I see that a major issue with the way DIP16 intends to shortcut fully qualified names is demonstrated by this simple example:

a/b/c.d:

module a.b.c;

void foo() {}
struct c
{
   static void foo() {}
}

main.d:
import a.b.c;

void main()
{
a.b.c.foo(); // cannot determine what this is. Is it the global function, or a shortcut FQN to a.b.c.c.foo?
}

This should be counter-case enough to disqualify that idea -- it will break existing code without ever adding any package.d files. Thanks for explaining.


I don't think option 1 is an improvement over what we have. I mean, if you're going to hide the submodules, what is the benefit compared to just using a different package name for the implementation modules?

The advantage is you can split your logical module into submodules for maintenance purposes.

You can already refactor std.algorithm this way with no change in the compiler:

        module std.algorithm;

        public import std.algorithm_impl.sort;
        public import std.algorithm_impl.map;
        public import std.algorithm_impl.blah_blah_blah;
        …

If we add a language feature, it should be an noticeable improvement over this situation.

I agree, option 1 is not very convincing.

I think we need a third option.

Here's an idea: we could allow modules having a single symbol with the same name as the module to behave as if they were the symbol itself, just like templates behaves. For instance:

        module std.algorithm.sort;

        void sort(int[] t);

Now you can import std.algorithm.sort and then use the std.algorithm.sort fully qualified name as if it was a function, even though it's the module name (std.algorithm.sort.sort would be the function's name).

Or maybe we could just allow "alias sort this" at module level? Or is it allowed already?

I don't like this proposal, simply because this means one function/symbol per submodule. It should be more flexible than that. But I like the line of thinking.

Let's re-examine the issue. We need to allow splitting of a module X.d into pieces for maintenance (or possibly accessibility -- disallowing friends). But we don't want to break code which currently uses FQN to access X's symbols.

I think the following might work:

algorithm.d:

import this = std.algorithm_impl.sort;

Which then imports std.algorithm_impl.sort, and effectively aliases all its symbols into algorithm.d. If std.algorithm_impl.sort defines a function called sort, then it's also aliased to std.algorithm.sort. In essence, sort has *two* FQN, but there are no FQN that refer to more than one symbol.

I purposely left out the package.d idea because it's orthogonal to this.

-Steve

Reply via email to