July 08, 2006
Kris escribió:
> In article <e8nq1e$16r$1@digitaldaemon.com>, Walter Bright says...
>> Walter Bright wrote:
>>>>> 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.
>> There's another way - have a different kind of import declaration, say, precede it with static:
>>
>> 	static import foo;
>>
>> which will make the symbols in foo available, but only if they are explicitly qualified. Then one could access bar in foo by either:
>>
>> 	foo.bar();
>>
>> or:
>>
>> 	alias foo.bar bar;
>> 	bar();
>>
>> but not:
>>
>> 	bar();	// error, undefined symbol
>>
>> The advantage of this is it is a bit more flexible and more consistent with the way the rest of D lookups work.
> 
> Er, that really doesn't work at all. Please ignore what I said a few minutes ago
> regarding this option (I really should get some sleep instead). 
> 
> The problem here is that, for the proposed static imports, everything must be
> fully-qualified with the /original import name/, and that's just plain awful for
> long import names. The "import as" allows one to give it a nice short name
> instead.
> 

But "static import" + "alias" would give us something closer to "import as" than the current "import" + "alias". Taking Sean previous example, if you have:

module some.guys.fancy.sql;
class connection { ... }

In your module you could do:

static import some.guys.fancy.sql;
alias some.guys.fancy.sql sql;

And you either use "sql.connection" or "some.guys.fancy.sql.connection", but connection wouldn't be available in the current namespace.

Now, I know it's more typing, it's two lines when you we could do it in one, but at least it would be an improvement (IMHO).

> And, I still think the selective-import is the superior solution anyway.
> 
> (I'd delete my earlier reply, but TBird is doing really wierd things with
> messages right now, and is basically hiding all my own posts)
> 
> 


-- 
Carlos Santander Bernal
July 08, 2006
Sean Kelly 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.
> 

What's really confusing is that module private is not really private and that there is not consistency!

> In D though, 'private' always implies module visibility, whether it it at module scope or class scope.  If the behavior at module scope is changed, would it affect its behavior at class scope as well?
> 
> 
> Sean
July 08, 2006
Walter Bright wrote:
> Derek Parnell wrote:
>> That why I wrote http://www.users.bigpond.com/ddparnell/attr.html but no one has bothered to comment it yet - including Walter whom I explicitly asked to.
> 
> I think it's a lot better than what I wrote about it.

Yes except in a couple of places that isn't how it works!
July 08, 2006
Sean Kelly 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.
> 
> In D though, 'private' always implies module visibility, whether it it at module scope or class scope.  If the behavior at module scope is changed, would it affect its behavior at class scope as well?

By the way, if private were changed at both module and class level, which I do think makes sense on some levels, this behavior would change:

    module main;

    class C
    {
    private:
        void fn() { printf( "C\n" ); }
    }

    void fn() { printf( "glob\n" ); }

    class D : C
    {
        void go() { fn(); }
    }

    void main()
    {
        D d = new D;
        d.go;
    }

Currently, this prints "C".  But if privates were truly private then I would expect it to either print "glob" or to get a compile error that two matching function were found and that D's call to 'fn' must be qualified by either prefixing it with a '.' or 'C.' to indicate intent.


Sean
July 08, 2006
Walter Bright wrote:
> Ivan Senji wrote:
>> 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.
> 
> Consider the following C++ code:
> 
> struct S
> {
>     public void foo(long);
>     private void foo(int);
> };
> struct T
> {
>     public void foo(long);
> };
> 
> ...
> 
> S s;
> s.foo(1);    // error, foo(int) is private
> T t;
> t.foo(1);    // ok
> 
> Note that it sees S::foo(int) and it participates in overload resolution even though it is private. In other words, accessibility is checked after lookup and after overload resolution.

I'm not sure this is an entirely valid example because private member functions in D are not inherited and therefore should never be considered for overload resolution in a derived class.  Assuming the new "truly invisible" private behavior, I would expect the lookup mechanism to first search the local class scope, then public/protected inherited scopes, then module scope, then imported module scopes.  Once a match is found, the overload mechanism should evaluate only the other visible functions at the scope of the match.  I'll admit that this sounds like it would require re-engineering the overload resolution code a bit, but I think the result would probably be more clear to the inexperienced user.


Sean
July 08, 2006
Sean Kelly wrote:
> Walter Bright wrote:
>> Ivan Senji wrote:
>>> 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.
>>
>> Consider the following C++ code:
>>
>> struct S
>> {
>>     public void foo(long);
>>     private void foo(int);
>> };
>> struct T
>> {
>>     public void foo(long);
>> };
>>
>> ...
>>
>> S s;
>> s.foo(1);    // error, foo(int) is private
>> T t;
>> t.foo(1);    // ok
>>
>> Note that it sees S::foo(int) and it participates in overload resolution even though it is private. In other words, accessibility is checked after lookup and after overload resolution.
> 
> I'm not sure this is an entirely valid example because private member functions in D are not inherited

I misspoke--they're not inherited in C++ either.  However, they can be overridden in C++ but not in D.  This is the pertinent distinction IMO.


Sean
July 08, 2006
Walter Bright wrote:
> Derek Parnell wrote:
>> I'm sorry Walter but I don't give newt's fart about C++. If I wanted to code under the rules of C++, I'd use C++. You have changed (improved) many of the C++ rules in D, so why not get this one right too?
> 
> I agree that D exists to fix broken rules in C++, but we need to understand the rationale for why they are the way they are in C++, else we run the risk of making a severe error. I don't recall why the access rules are the way they are in C++, but I do know they weren't don't that way for backwards compatibility.

Please see my post here:

http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/39072

According to Daveed Vandevoorde:

   The fact that private members are inaccessible but not invisible
   regularly surprises incidental programmers. Like macros, seemingly
   unrelated declarations interfere with subsequent code. Unfortunately,
   there are good reasons for this state of affair: Without it, private
   out-of-class member declarations become impractical to parse in the
   general case.

So assuming he's right (I couldn't find the minutes of the original meetings to back up his claim) then the decision was made fore purely technical reasons, and reasons that don't seem to apply to D because of the different meaning of 'private'.  Daveed goes on to say:

   Module namespaces appear to be an ideal boundary for making the
   private member fully invisible: Within the module the implementer has
   full control over naming conventions and can therefore easily avoid
   interference, while outside the module the client will never
   have to implement private members. (Note that this also addresses the
   concerns of N1602 "Class Scope Using Declarations & private Members"
   by Francis Glassborow; the extension proposed therein is then no
   longer needed.)

(note that this is the proposal for modules in C++)

I know you've read the proposal, but it's available here for those who don't want to follow my link above:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1964.pdf


Sean
July 08, 2006
Derek Parnell wrote:
> On Sat, 08 Jul 2006 18:07:34 +1000, Ivan Senji <ivan.senji_REMOVE_@_THIS__gmail.com> wrote:
> 
>> Derek Parnell wrote:
>>> On Sat, 08 Jul 2006 14:47:34 +1000, Walter Bright
>>> <newshound@digitalmars.com> wrote:
>>>
>>>> Brad Roberts wrote:
>>>
>>>>>  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.
>>>
>>> No.... what would happen if something outside the module called
>>> foo(long) is that foo(int) would be called due to implicit casts and
>>> that the module's foo(long) is invisible to the caller. It wouldn't be
>>> called because the caller should not be able to see it.
>>>
>>
>> Yes, but:
>> If the functions were actually:
>>
>> void foo(int x);
>> private void foo(char[] x);
>>
>> and in another module foo("bar"); the right function would be called
>> even though it is private.
>> The problem: the caller does see it if there is another function with
>> the same name.
> 
> I agree that that is the problem. Calling foo("bar") should fail as that is private to the module and the caller should not be able to access it *BECAUSE* it is private even though the compiler can actually 'see' it.
> 

Exactly - and then it would (and should!) act just like if you wrapped a class or struct around it (and this should apply even if you declared it as a private static class or struct member). I mean the consistency considerations of this to the average dumbass user like me are huge.

The first example points this out here:

http://www.users.bigpond.com/ddparnell/attr.html

private should act the same no matter what the enclosing scope is.

> --Derek Parnell
> Melbourne, Australia
July 08, 2006
Derek Parnell wrote:
> On Sat, 08 Jul 2006 13:36:49 +1000, Walter Bright <newshound@digitalmars.com> wrote:
> 
> 
>> But the suggestions involve changing the importer code, too. I'm not seeing the advantage of that over fully qualifying the references or using an alias, both of which will ensure that no future imports will cause name collisions.
> 
> I tend to agree with Walter on this one. The only thing that might be needed in a post 1.0 edition of D is some syntax help to make the job of tedious alias coding a lot easier.
> 
>> 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.
> 
> Not a bad idea at all.
> 
>> What can also be done is extend the import declaration to allow the .'s to continue so that specific symbols can be imported.
> 
> An excellent idea because it does the job and follows the consistent look of D. Makes my job in Build a bit harder though ;-)
> 

Completely agree.

> --Derek Parnell
> Melbourne, Australia
July 08, 2006
Sean Kelly wrote:
> Please see my post here:

Thanks for the reference. This rule, however, long predates Daveed's involvement with C++. I want to do a little more research on this.
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18