August 26, 2004
On Thu, 26 Aug 2004 14:28:32 +1200, Regan Heath wrote:

> On Wed, 25 Aug 2004 22:05:58 -0400, Ant <duitoolkit@yahoo.ca> wrote:
>> On Thu, 26 Aug 2004 11:49:49 +1200, Regan Heath wrote:
>>
>>>
>>> This small example exhibits that behaviour:
>>
>> That shows the same as my original example.
>> Walter confirmed this is the desired behaviour.
> 
> Can Walter please re-confim that for me...

I knew my reputation was low, but... ;)

follow the link I provided for the bugs group until;

"
The idea of name lookup happening, *then* overload resolution, operates the
same as in C++. It's a chicken-and-egg problem to try to do it based on type
signatures because of implicit conversions.
"

Ant

August 26, 2004
On Wed, 25 Aug 2004 22:41:10 -0400, Ant <duitoolkit@yahoo.ca> wrote:
> On Thu, 26 Aug 2004 14:28:32 +1200, Regan Heath wrote:
>
>> On Wed, 25 Aug 2004 22:05:58 -0400, Ant <duitoolkit@yahoo.ca> wrote:
>>> On Thu, 26 Aug 2004 11:49:49 +1200, Regan Heath wrote:
>>>
>>>>
>>>> This small example exhibits that behaviour:
>>>
>>> That shows the same as my original example.
>>> Walter confirmed this is the desired behaviour.
>>
>> Can Walter please re-confim that for me...
>
> I knew my reputation was low, but... ;)
>
> follow the link I provided for the bugs group until;
>
> "
> The idea of name lookup happening, *then* overload resolution, operates the
> same as in C++. It's a chicken-and-egg problem to try to do it based on type
> signatures because of implicit conversions.
> "

Yeah.. I remember those discussions.. I don't think the statement above is 100% to do with this particular example because there is no implicit conversion going on.

Instead, it simply appears to pick the imported 'read' symbol in favour of the base class 'read' (which hasn't been overloaded in the child). If you _do_ overload the base 'read' in child then it gets it right, presumably for the same reason as in bens example.

The import drags the symbols into the current scope, so the imported 'read' is technically overloading the base class 'read'. BUT. why then doesn't this cause an error when the current scope already has a read symbol? (as in bens example)

Something is just not quite right.

Regan

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
August 26, 2004
I have gone one step further in this problem, this code...

--[mod1.d]--
module mod1;

void read() {
  printf("read\n");
}

--[mod2.d]--
module mod2;

class Base {
  final void read() {
    printf("Base::read\n");
  }
}

class Child : Base {
  import mod1;

/*  void read() {
    printf("Child::read\n");
  }*/

  void foo() {
    read();
  }
}

void main()
{
  Child c = new Child();
  c.foo();
}

compiles, runs and prints "read".

so the import overloads the 'final' read class from the Base class.
Uncommenting the 'read' in the Child causes the expected compile error.

Regan

On Thu, 26 Aug 2004 14:57:31 +1200, Regan Heath <regan@netwin.co.nz> wrote:

> On Wed, 25 Aug 2004 22:41:10 -0400, Ant <duitoolkit@yahoo.ca> wrote:
>> On Thu, 26 Aug 2004 14:28:32 +1200, Regan Heath wrote:
>>
>>> On Wed, 25 Aug 2004 22:05:58 -0400, Ant <duitoolkit@yahoo.ca> wrote:
>>>> On Thu, 26 Aug 2004 11:49:49 +1200, Regan Heath wrote:
>>>>
>>>>>
>>>>> This small example exhibits that behaviour:
>>>>
>>>> That shows the same as my original example.
>>>> Walter confirmed this is the desired behaviour.
>>>
>>> Can Walter please re-confim that for me...
>>
>> I knew my reputation was low, but... ;)
>>
>> follow the link I provided for the bugs group until;
>>
>> "
>> The idea of name lookup happening, *then* overload resolution, operates the
>> same as in C++. It's a chicken-and-egg problem to try to do it based on type
>> signatures because of implicit conversions.
>> "
>
> Yeah.. I remember those discussions.. I don't think the statement above is 100% to do with this particular example because there is no implicit conversion going on.
>
> Instead, it simply appears to pick the imported 'read' symbol in favour of the base class 'read' (which hasn't been overloaded in the child). If you _do_ overload the base 'read' in child then it gets it right, presumably for the same reason as in bens example.
>
> The import drags the symbols into the current scope, so the imported 'read' is technically overloading the base class 'read'. BUT. why then doesn't this cause an error when the current scope already has a read symbol? (as in bens example)
>
> Something is just not quite right.
>
> Regan
>



-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
August 26, 2004
Regan Heath wrote:

> On Wed, 25 Aug 2004 22:05:58 -0400, Ant <duitoolkit@yahoo.ca> wrote:
>> On Thu, 26 Aug 2004 11:49:49 +1200, Regan Heath wrote:
>>
>>>
>>> This small example exhibits that behaviour:
>>
>> That shows the same as my original example.
>> Walter confirmed this is the desired behaviour.
> 
> Can Walter please re-confim that for me...
> Walter, Ant is saying that this code:
> 
> <ben's example>
> I tried again with
> file mod1.d:
> module mod1;
> void foo(){printf("hello\n");};
> 
> file mod2.d:
> module mod2;
> class A {
>    import mod1;
>    void foo(){printf("in A\n");};
>    void bar(){ foo(); }
> }
> void main(){
> A a = new A;
> a.bar();
> };
> 
> and it prints "in A" as I would expect. So it looks like the right one is
> found.
> </ben's example>
> 
> and this code
> 
> <my example>
> --[mod1.d]--
> module mod1;
> 
> void read() {
>    printf("read\n");
> }
> 
> --[mod2.d]--
> module mod2;
> 
> class Base {
>    void read() {
>      printf("Base::read\n");
>    }
> }
> 
> class Child : Base {
>    import mod1;
> 
>    void foo() {
>      read();
>    }
> }
> 
> void main()
> {
>    Child c = new Child();
>    c.foo();
> }
> 
> c.foo calls 'read' which calls mod1.read, NOT, mod2.Base.read. </my example>
> 
> Exhibit the desired behaviour?
> 
> It appears it's the name resolution rules again. In my example it finds the imported symbol before it finds the base class symbol. In ben's it finds the local symbol before the imported symbol.

I can't find the message now but a while ago Walter listed the steps
involved in name lookup and it went a little something like this:
- symbols in current scope
- symbols in imports in current scope
- symbols in base classes
- repeat with next outer scope

The function search() in files src/dmd/class.c, dsymbol.c and scope.d probably are where the logic lies. Basically look at Scope::search, ScopeDsymbol::search and ClassDeclaration::search. I don't know if Walter really wanted that behavior or if it just does what it does without having strong language reasons why imports take precedence over superclasses. It does seem a little wierd that imports are searched before superclasses - maybe that's why Walter discourages them.

> I believe Ant desires that the base symbol would be found before the imported symbol.
> 
> Are imports supposed to overload (correct term?) class methods? If so, why doesn't it overload in bens example?
> 
>> That's when I decided that D can't be used
>> with anything else but strict 00. Which suit me fine!
> 
> I've not given up on this yet..
> 
> Regan
> 

August 26, 2004
Ant wrote:
> On Thu, 26 Aug 2004 11:49:49 +1200, Regan Heath wrote:
> 
> 
>>This small example exhibits that behaviour:
> 
> 
> That shows the same as my original example.
> Walter confirmed this is the desired behaviour.
> That's when I decided that D can't be used with anything else but strict 00. Which suit me fine!

I've never had any problems before.  I just keep imports private and at the module level.  Everything works exactly as I expect it.

Also, what's "strict OO"?

 -- andy
August 26, 2004
Ben Hinkle wrote:
> Regan Heath wrote:
> 
...
>>It appears it's the name resolution rules again. In my example it finds
>>the imported symbol before it finds the base class symbol. In ben's it
>>finds the local symbol before the imported symbol.
> 
> 
> I can't find the message now but a while ago Walter listed the steps

I think I tracked it down: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/6978

<quote>
How name lookup happens in a scope is a
multi-stage process, each proceeding to the next if the name is not found in
the current stage:

    1) look for a member with the name
    2) look in any imports *in this scope*
    3) if current scope is a class scope, recursively look in base classes
    4) repeat the process with the most enclosing scope

I think it would be very strange to have base class symbols override imports
in the current scope, i.e. if imports were looked up in some other scope
than the one in which they were imported.
</quote>

> involved in name lookup and it went a little something like this:
> - symbols in current scope
> - symbols in imports in current scope
> - symbols in base classes
> - repeat with next outer scope
> 
> The function search() in files src/dmd/class.c, dsymbol.c and scope.d
> probably are where the logic lies. Basically look at Scope::search,
> ScopeDsymbol::search and ClassDeclaration::search. I don't know if Walter
> really wanted that behavior or if it just does what it does without having
> strong language reasons why imports take precedence over superclasses. It
> does seem a little wierd that imports are searched before superclasses -
> maybe that's why Walter discourages them.



-- 
Justin (a/k/a jcc7)
http://jcc_7.tripod.com/d/
August 26, 2004
On Wed, 25 Aug 2004 20:32:16 -0700, Andy Friesen wrote:

> Ant wrote:
>> On Thu, 26 Aug 2004 11:49:49 +1200, Regan Heath wrote:
>> 
>> 
>>>This small example exhibits that behaviour:
>> 
>> 
>> That shows the same as my original example.
>> Walter confirmed this is the desired behaviour.
>> That's when I decided that D can't be used
>> with anything else but strict 00. Which suit me fine!
> 
> I've never had any problems before.

are you kiding?
I've never NOT had any problems before.

> I just keep imports private and at the module level.

tried that, didn't work.

>  Everything works exactly as I expect it.

lucky

> 
> Also, what's "strict OO"?

just my way of saying NO to global/free/independent functions.

well, my original idea is completly lost on this thread...

Ant

August 26, 2004
> 
> IIRC it was that the import was overloading a base class method, like 'pause' in threads or 'read' in a buffer class?
> 
> This small example exhibits that behaviour:
> --[mod1.d]--
> module mod1;
> 
> void read() {
>   printf("read\n");
> }
> 
> --[mod2.d]--
> module mod2;
> 
> class Base {
>   void read() {
>     printf("Base::read\n");
>   }
> }
> 
> class Child : Base {
>   import mod1;
> 
>   void foo() {
>     read();
>   }
> }
> 
> void main()
> {
>   Child c = new Child();
>   c.foo();
> }
> 
> c.foo calls 'read' which calls mod1.read, NOT, mod2.Base.read.
> 
> <snip>
> 
> Regan
> 

Ah yes! That was the example I was looking for.  It seems I forgot the exact nature of the issue.  Thanks for pointing that out.  The issue must still exists then.
August 26, 2004
Yes, that does describe the issue quite succintly.  The non-overriden read from the base class is hidden by the import statement.  It's funny I could never work up an example that showed this.  Good to know!
August 26, 2004
On Wed, 25 Aug 2004 21:39:04 -0700, John Reimer <brk_6502@NOSP_AM.yahoo.com> wrote:

>
>>
>> IIRC it was that the import was overloading a base class method, like 'pause' in threads or 'read' in a buffer class?
>>
>> This small example exhibits that behaviour:
>> --[mod1.d]--
>> module mod1;
>>
>> void read() {
>>   printf("read\n");
>> }
>>
>> --[mod2.d]--
>> module mod2;
>>
>> class Base {
>>   void read() {
>>     printf("Base::read\n");
>>   }
>> }
>>
>> class Child : Base {
>>   import mod1;
>>
>>   void foo() {
>>     read();
>>   }
>> }
>>
>> void main()
>> {
>>   Child c = new Child();
>>   c.foo();
>> }
>>
>> c.foo calls 'read' which calls mod1.read, NOT, mod2.Base.read.
>>
>> <snip>
>>
>> Regan
>>
>
> Ah yes! That was the example I was looking for.  It seems I forgot the exact nature of the issue.  Thanks for pointing that out.  The issue must still exists then.

Yes, it's the intended behaviour:

<quote>
How name lookup happens in a scope is a
multi-stage process, each proceeding to the next if the name is not found in
the current stage:

    1) look for a member with the name
    2) look in any imports *in this scope*
    3) if current scope is a class scope, recursively look in base classes
    4) repeat the process with the most enclosing scope

I think it would be very strange to have base class symbols override imports
in the current scope, i.e. if imports were looked up in some other scope
than the one in which they were imported.
</quote>

Why is why Walter discourages import inside a class.

Regan

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/