DIP16: Transparently substitute module with package

Steven Schveighoffer schveiguy at yahoo.com
Thu Apr 5 04:46:38 PDT 2012


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

> On 2012-04-04 19:48:32 +0000, "Steven Schveighoffer"  
> <schveiguy at yahoo.com> said:
>
>> On Wed, 04 Apr 2012 14:03:07 -0400, Timon Gehr <timon.gehr at 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


More information about the Digitalmars-d mailing list