July 08, 2006
Walter Bright wrote:
> Derek Parnell wrote:
>> On Sat, 08 Jul 2006 06:56:47 +1000, Walter Bright <newshound@digitalmars.com> wrote:
>>
>>> The alias works at any level you choose to make it. Alias can be used to 'import' any name into the current namespace, making it first class.
>>
>> Even names that are declared 'private' in the imported module? Is that how you want it to work Walter? If so, why do we bother with 'private'? What's the point?
> 
> In class scope, access control is done *after* name lookup, not before. I'm concerned about confusion by reversing the order of that for module scope.

How much begging would it take to try for a release or two having private symbols invisible to the importer?  It's really much more intuitive, imho.  I haven't looked at this part of the front end code, but if it's easy, feel free to make it controllable via a compiler option just for the experiment's time frame.

Later,
Brad
July 08, 2006
Walter Bright wrote:
> What can be done is something like add a warning whenever a name is found using the second-class import lookup, rather than using an alias or a fully qualified lookup. Then, you'll be able to easily purge your code of any such, and be confident that adding other modules will not break your existing code.

I perhaps don't quite follow that completely. But it sounds like you're saying all names would have to be fully qualified at all times, unless they're declared within the enclosing module? If not, then forgive me for not following correctly.

If so, I think that would overly restrictive, and would perhaps encourage a slew of aliases just to make things work correctly. I think that would be detrimental, since those who wish to write Q&D code would find themselves prejudiced against. The "import x.y.z as foo;" syntax suggested is purely an option for those who care about ensuring the namespaces are fully isolated ~ and is a clean way to do it for an entire module as a time. e.g. with the "as" syntax, the following would operate without conflict:

---
module a;

int foo() {...}

---
module b;

int foo() {...}

---
module main;

import a;
import b as other;

void main()
{
	foo();       // a.foo
	other.foo()  // b.foo;
}

In this trivial example, you could do the same with an alias. However, an alias would /potentially/ be needed for every symbol within module b, whereas the "as" handles all of that cleanly. Consider the effort to manually alias each symbol from each imported modules that may potentially change over time? Import "as" does it cleanly instead.

However, I think this next option is preferable:


> What can also be done is extend the import declaration to allow the .'s to continue so that specific symbols can be imported.

Now that would be great. I believe selective-importing (as an option) would be a boon in a number of ways ~ and would resolve this issue quite elegantly.

Neither of these would have any effect on existing code, so there's no concern over backward compatability. But it could be argued that the latter case is notably more explicit, and perhaps avoids an additional renaming step within the compiler.
July 08, 2006
Brad Roberts wrote:
> Walter Bright wrote:
>> Derek Parnell wrote:
>>> On Sat, 08 Jul 2006 06:56:47 +1000, Walter Bright <newshound@digitalmars.com> wrote:
>>>
>>>> The alias works at any level you choose to make it. Alias can be used to 'import' any name into the current namespace, making it first class.
>>>
>>> Even names that are declared 'private' in the imported module? Is that how you want it to work Walter? If so, why do we bother with 'private'? What's the point?
>>
>> In class scope, access control is done *after* name lookup, not before. I'm concerned about confusion by reversing the order of that for module scope.
> 
> How much begging would it take to try for a release or two having private symbols invisible to the importer?  It's really much more intuitive, imho.  I haven't looked at this part of the front end code, but if it's easy, feel free to make it controllable via a compiler option just for the experiment's time frame.

The problems happen when one has:

void foo(int x);
private void foo(long x);

So the first foo is found, then overload rules apply, and the second foo is selected.
July 08, 2006
kris wrote:
> Walter Bright wrote:
>> What can be done is something like add a warning whenever a name is found using the second-class import lookup, rather than using an alias or a fully qualified lookup. Then, you'll be able to easily purge your code of any such, and be confident that adding other modules will not break your existing code.
> 
> I perhaps don't quite follow that completely. But it sounds like you're saying all names would have to be fully qualified at all times, unless they're declared within the enclosing module?

Yes.

> ---
> module a;
> 
> int foo() {...}
> 
> ---
> module b;
> 
> int foo() {...}
> 
> ---
> module main;
> 
> import a;
> import b as other;
> 
> void main()
> {
>     foo();       // a.foo
>     other.foo()  // b.foo;
> }
> 
> In this trivial example, you could do the same with an alias. However, an alias would /potentially/ be needed for every symbol within module b, whereas the "as" handles all of that cleanly. Consider the effort to manually alias each symbol from each imported modules that may potentially change over time? Import "as" does it cleanly instead.

What I don't like about that proposal is the same reason you didn't like the warning proposal above - you'd be forced to fully qualify all references to names within b.

> However, I think this next option is preferable:
> 
> 
>> What can also be done is extend the import declaration to allow the .'s to continue so that specific symbols can be imported.
> 
> Now that would be great. I believe selective-importing (as an option) would be a boon in a number of ways ~ and would resolve this issue quite elegantly.

I like this one better, too.


> Neither of these would have any effect on existing code, so there's no concern over backward compatability. But it could be argued that the latter case is notably more explicit, and perhaps avoids an additional renaming step within the compiler.
July 08, 2006
Walter Bright wrote:
> Brad Roberts wrote:
[snip]
>> How much begging would it take to try for a release or two having private symbols invisible to the importer?  It's really much more intuitive, imho.  I haven't looked at this part of the front end code, but if it's easy, feel free to make it controllable via a compiler option just for the experiment's time frame.
> 
> 
> The problems happen when one has:
> 
> void foo(int x);
> private void foo(long x);
> 
> So the first foo is found, then overload rules apply, and the second foo is selected.


So, in D, what does private actually mean? The verbose version if you wouldn't mind, with all known corner-cases noted?

I think the full explanation would help a lot, since it's often easier to remember the things one should not do, rather than those one should.
July 08, 2006
Walter Bright wrote:
> kris wrote:
> 
>> Walter Bright wrote:
>>
>>> What can be done is something like add a warning whenever a name is found using the second-class import lookup, rather than using an alias or a fully qualified lookup. Then, you'll be able to easily purge your code of any such, and be confident that adding other modules will not break your existing code.
>>
>>
>> I perhaps don't quite follow that completely. But it sounds like you're saying all names would have to be fully qualified at all times, unless they're declared within the enclosing module?
> 
> 
> Yes.
> 
>> ---
>> module a;
>>
>> int foo() {...}
>>
>> ---
>> module b;
>>
>> int foo() {...}
>>
>> ---
>> module main;
>>
>> import a;
>> import b as other;
>>
>> void main()
>> {
>>     foo();       // a.foo
>>     other.foo()  // b.foo;
>> }
>>
>> In this trivial example, you could do the same with an alias. However, an alias would /potentially/ be needed for every symbol within module b, whereas the "as" handles all of that cleanly. Consider the effort to manually alias each symbol from each imported modules that may potentially change over time? Import "as" does it cleanly instead.
> 
> 
> What I don't like about that proposal is the same reason you didn't like the warning proposal above - you'd be forced to fully qualify all references to names within b.
> 
>> However, I think this next option is preferable:
>>
>>
>>> What can also be done is extend the import declaration to allow the .'s to continue so that specific symbols can be imported.
>>
>>
>> Now that would be great. I believe selective-importing (as an option) would be a boon in a number of ways ~ and would resolve this issue quite elegantly.
> 
> 
> I like this one better, too.


As FatFreddy would have noted, "Well, I'll be dipped in dogshit ..."
July 08, 2006
kris wrote:
> So, in D, what does private actually mean? The verbose version if you wouldn't mind, with all known corner-cases noted?
> 
> I think the full explanation would help a lot, since it's often easier to remember the things one should not do, rather than those one should.

It means the same thing as in C++. It should give an error if you try to access a private member in another module - but the symbol is still found.
July 08, 2006
Walter Bright wrote:
> Brad Roberts wrote:
>> Walter Bright wrote:
>>> Derek Parnell wrote:
>>>> On Sat, 08 Jul 2006 06:56:47 +1000, Walter Bright <newshound@digitalmars.com> wrote:
>>>>
>>>>> The alias works at any level you choose to make it. Alias can be used to 'import' any name into the current namespace, making it first class.
>>>>
>>>> Even names that are declared 'private' in the imported module? Is that how you want it to work Walter? If so, why do we bother with 'private'? What's the point?
>>>
>>> In class scope, access control is done *after* name lookup, not before. I'm concerned about confusion by reversing the order of that for module scope.
>>
>> How much begging would it take to try for a release or two having private symbols invisible to the importer?  It's really much more intuitive, imho.  I haven't looked at this part of the front end code, but if it's easy, feel free to make it controllable via a compiler option just for the experiment's time frame.
> 
> The problems happen when one has:
> 
> void foo(int x);
> private void foo(long x);
> 
> So the first foo is found, then overload rules apply, and the second foo is selected.

Ok, I think I get it: module level private in D means exactly *nothing*.

:)

How does this sound in the documentation:
"A module level function that is declared private can not be used in
another module unless there is another public function with the same name."
<- This is just crazy(or does it justsound crazy to me), IMO private
"void foo(long x);" in the above example should not be included in the
overload resolution.

July 08, 2006
Walter Bright wrote:
> kris wrote:
>>
>> module main;
>>
>> import a;
>> import b as other;
>>
>> void main()
>> {
>>     foo();       // a.foo
>>     other.foo()  // b.foo;
>> }
>>
>> In this trivial example, you could do the same with an alias. However, an alias would /potentially/ be needed for every symbol within module b, whereas the "as" handles all of that cleanly. Consider the effort to manually alias each symbol from each imported modules that may potentially change over time? Import "as" does it cleanly instead.
> 
> What I don't like about that proposal is the same reason you didn't like the warning proposal above - you'd be forced to fully qualify all references to names within b.

And that's why I suggested it could be syntactic sugar for an alias declaration instead, thus making the qualifier optional.  That said, it's worth noting that "other" as a user-chosen alias will likely be far shorter than the package/module name they represent.  I would much rather say "sql.connection" than "some.guys.fancy.sql.connection."

>> However, I think this next option is preferable:
>>
>>> What can also be done is extend the import declaration to allow the .'s to continue so that specific symbols can be imported.
>>
>> Now that would be great. I believe selective-importing (as an option) would be a boon in a number of ways ~ and would resolve this issue quite elegantly.
> 
> I like this one better, too.

Same here.


Sean
July 08, 2006
Walter Bright wrote:
> Brad Roberts wrote:
>> Walter Bright wrote:
>>> Derek Parnell wrote:
>>>> On Sat, 08 Jul 2006 06:56:47 +1000, Walter Bright <newshound@digitalmars.com> wrote:
>>>>
>>>>> The alias works at any level you choose to make it. Alias can be used to 'import' any name into the current namespace, making it first class.
>>>>
>>>> Even names that are declared 'private' in the imported module? Is that how you want it to work Walter? If so, why do we bother with 'private'? What's the point?
>>>
>>> In class scope, access control is done *after* name lookup, not before. I'm concerned about confusion by reversing the order of that for module scope.
>>
>> How much begging would it take to try for a release or two having private symbols invisible to the importer?  It's really much more intuitive, imho.  I haven't looked at this part of the front end code, but if it's easy, feel free to make it controllable via a compiler option just for the experiment's time frame.
> 
> The problems happen when one has:
> 
> void foo(int x);
> private void foo(long x);
> 
> So the first foo is found, then overload rules apply, and the second foo is selected.

Um.. finding the second foo means that it's not invisible.  It should not exist as far as anything outside the module is concerned.  It's private, internal, period.  About the only part of existence that a private symbol has is in determining the size of a struct or class.  But beyond occupying space, it shouldn't have any interaction at all.  They just shouldn't exist in the symbol table at all.

Is there something about private symbols existing that all the rest of us are over looking that makes it important for them to be visible?

Later,
Brad