Thread overview
Angry citizen stikes once again. forward references problems
Jul 30, 2006
Derek
Jul 30, 2006
Derek Parnell
Jul 31, 2006
kris
Jul 31, 2006
Derek Parnell
July 30, 2006
Nested classes, enums and such are unusable if there are any circular imports. If you have got no luck you get:

   `class X is forward referenced when looking for Y'

error and the only way to have it compile is too change compilation order. (there was many such posts on D.learn and D.bugs). If you're using dbuild for that - you can only pray not to hit that problem or not to use nested things at all.

In extremal situations you can even get something you can't compile in any
way:
http://d.puremagic.com/issues/show_bug.cgi?id=104

This is one of those things that makes me irritated each time I'm dealing with D, because I use nested logic in classes much. And this is one of errors that are blockers for DMD 1.0. You can't write serious projects using D till such errors exists.

I hope that after fixing import conflict problems in 163 (good work BTW) now has come time to fix other import problems - especially this one.

Thanks you for your attention.
July 30, 2006
Dawid Ciężarkiewicz wrote:
> In extremal situations you can even get something you can't compile in any
> way:
> http://d.puremagic.com/issues/show_bug.cgi?id=104

I mean:
http://d.puremagic.com/issues/show_bug.cgi?id=102

Sorry.
July 30, 2006
On Sun, 30 Jul 2006 21:55:59 +0200, Dawid Ciężarkiewicz wrote:

> Dawid Ciężarkiewicz wrote:
>> In extremal situations you can even get something you can't compile in any
>> way:
>> http://d.puremagic.com/issues/show_bug.cgi?id=104
> 
> I mean:
> http://d.puremagic.com/issues/show_bug.cgi?id=102

I don't understand this Dawid. It seems you are trying to use a nested class inside another class, and I'm sure you can't and shouldn't do that.

I thought the purpose of nested classes was to restrict the scope of the nested class to its parent and thus trying to use it outside of the parent doesn't seem right to me.

Your example..
//  --- test2.d -----
import test2;
class X
{
  Y.NY t;  // ?!? But NY is defined as a nested class in Y.
  static class NX
  {
  }
}
//-------------------------//


//  --- test.d -----
import test;
class Y
{
  X.NX nx;  // ?!? But NX is defined as a nested class in X.
  static class NY
  {
  }
}
//-------------------------//


D won't let you do even the more simple case ...

//------- test3.d -----
class X
{
  static class NX
  {
  }
}

class Y
{
     NX q; // test3.d(10): identifier 'NX' is not defined
}
// -------------------- //

I think dmd is working correctly, though the error messages are not exactly helpful.

-- 
Derek Parnell
Melbourne, Australia
"Down with mediocrity!"
July 30, 2006
"Derek" <derek@psyc.ward> wrote in message news:zbzgquaqpewl$.brpiyqr0sclz.dlg@40tude.net...
> I don't understand this Dawid. It seems you are trying to use a nested class inside another class, and I'm sure you can't and shouldn't do that.

Why not?  What about a parent "factory" class, which needs to create instances of a nested class, which the user can use?  The nested class can still access its outer class, and the user can use the nested class instances just fine.

> I thought the purpose of nested classes was to restrict the scope of the nested class to its parent and thus trying to use it outside of the parent doesn't seem right to me.

Sometimes that's true.  Sometimes you just want the nested class to have access to the outer class.  Granted, you can do this with friend classes, but.. as mentioned above, if you want an "owner/owned" relationship between the classes, using a nested class seems somewhat more elegant.

> D won't let you do even the more simple case ...
>
> //------- test3.d -----
> class X
> {
>  static class NX
>  {
>  }
> }
>
> class Y
> {
>     NX q; // test3.d(10): identifier 'NX' is not defined
> }
> // -------------------- //
>
> I think dmd is working correctly, though the error messages are not
> exactly
> helpful.

Namespaces, namespaces.

Class Y
{
    X.NX q;
}

And you could even "alias X.NX NX;" if you wanted to.

In addition, you'll notice that Walter even added syntax in a recent update to allow you to create instances of nested classes using an outer class reference:

X x = new X;
X.NX nx = x.new NX;

Which seems like you're almost.. well maybe not _encouraged_ but certainly not _blocked from_ creating instances of nested classes outside the owner class.


July 30, 2006
Your example is incorrect.  It should be:

class X
{
   static class NX
   {
   }
}

class Y
{
   X.NX q;
}

Which compiles, indeed.

That said, I don't use a lot of cycles as far as nested classes... honestly it feels weird to me (as you said.)

So can't... actually you can.  Shouldn't... hmm, yeah.  Gotta love conventions, some are good, some are weird.

-[Unknown]


> On Sun, 30 Jul 2006 21:55:59 +0200, Dawid Ciężarkiewicz wrote:
> 
>> Dawid Ciężarkiewicz wrote:
>>> In extremal situations you can even get something you can't compile in any
>>> way:
>>> http://d.puremagic.com/issues/show_bug.cgi?id=104
>> I mean:
>> http://d.puremagic.com/issues/show_bug.cgi?id=102
> 
> I don't understand this Dawid. It seems you are trying to use a nested
> class inside another class, and I'm sure you can't and shouldn't do that.
> 
> I thought the purpose of nested classes was to restrict the scope of the
> nested class to its parent and thus trying to use it outside of the parent
> doesn't seem right to me.
> 
> Your example..
> //  --- test2.d -----
> import test2;
> class X
> {
>   Y.NY t;  // ?!? But NY is defined as a nested class in Y.
>   static class NX
>   {
>   }
> }
> //-------------------------//
> 
> 
> //  --- test.d -----
> import test;
> class Y
> {
>   X.NX nx;  // ?!? But NX is defined as a nested class in X.
>   static class NY
>   {
>   }
> }
> //-------------------------//
> 
> 
> D won't let you do even the more simple case ...
> 
> //------- test3.d -----
> class X
> {
>   static class NX
>   {
>   }
> }
> 
> class Y
> {
>      NX q; // test3.d(10): identifier 'NX' is not defined
> }
> // -------------------- //
> 
> I think dmd is working correctly, though the error messages are not exactly
> helpful.
> 
July 30, 2006
On Sun, 30 Jul 2006 18:57:14 -0400, Jarrett Billingsley wrote:

> "Derek" <derek@psyc.ward> wrote in message news:zbzgquaqpewl$.brpiyqr0sclz.dlg@40tude.net...
>> I don't understand this Dawid. It seems you are trying to use a nested class inside another class, and I'm sure you can't and shouldn't do that.
> 
> Why not?  What about a parent "factory" class, which needs to create instances of a nested class, which the user can use?  The nested class can still access its outer class, and the user can use the nested class instances just fine.
> 
>> I thought the purpose of nested classes was to restrict the scope of the nested class to its parent and thus trying to use it outside of the parent doesn't seem right to me.
> 
> Sometimes that's true.  Sometimes you just want the nested class to have access to the outer class.  Granted, you can do this with friend classes, but.. as mentioned above, if you want an "owner/owned" relationship between the classes, using a nested class seems somewhat more elegant.

Okay ... but why would you want a nested class to be used as a type inside another class? Seems like a silly thing to do. What's the advantage of doing that?

>> D won't let you do even the more simple case ...
>>
>> //------- test3.d -----
>> class X
>> {
>>  static class NX
>>  {
>>  }
>> }
>>
>> class Y
>> {
>>     NX q; // test3.d(10): identifier 'NX' is not defined
>> }
>> // -------------------- //
>>
>> I think dmd is working correctly, though the error messages are not
>> exactly
>> helpful.
> 
> Namespaces, namespaces.
> 
> Class Y
> {
>     X.NX q;
> }
> 
> And you could even "alias X.NX NX;" if you wanted to.

Seems wrong to me. I can't see why one would bother making obscure,
hard-to-maintain, hard-to-read classes definitions using this technique.
Seems counter-productive.


-- 
Derek
(skype: derek.j.parnell)
Melbourne, Australia
"Down with mediocrity!"
31/07/2006 9:46:30 AM
July 31, 2006
Derek Parnell wrote:
> On Sun, 30 Jul 2006 18:57:14 -0400, Jarrett Billingsley wrote:
> 
> 
>>"Derek" <derek@psyc.ward> wrote in message news:zbzgquaqpewl$.brpiyqr0sclz.dlg@40tude.net...
>>
>>>I don't understand this Dawid. It seems you are trying to use a nested
>>>class inside another class, and I'm sure you can't and shouldn't do that.
>>
>>Why not?  What about a parent "factory" class, which needs to create instances of a nested class, which the user can use?  The nested class can still access its outer class, and the user can use the nested class instances just fine.
>>
>>
>>>I thought the purpose of nested classes was to restrict the scope of the
>>>nested class to its parent and thus trying to use it outside of the parent
>>>doesn't seem right to me.
>>
>>Sometimes that's true.  Sometimes you just want the nested class to have access to the outer class.  Granted, you can do this with friend classes, but.. as mentioned above, if you want an "owner/owned" relationship between the classes, using a nested class seems somewhat more elegant.
> 
> 
> Okay ... but why would you want a nested class to be used as a type inside
> another class? Seems like a silly thing to do. What's the advantage of
> doing that?
> 
> 
>>>D won't let you do even the more simple case ...
>>>
>>>//------- test3.d -----
>>>class X
>>>{
>>> static class NX
>>> {
>>> }
>>>}
>>>
>>>class Y
>>>{
>>>    NX q; // test3.d(10): identifier 'NX' is not defined
>>>}
>>>// -------------------- //
>>>
>>>I think dmd is working correctly, though the error messages are not exactly
>>>helpful.
>>
>>Namespaces, namespaces.
>>
>>Class Y
>>{
>>    X.NX q;
>>}
>>
>>And you could even "alias X.NX NX;" if you wanted to.
> 
> 
> Seems wrong to me. I can't see why one would bother making obscure,
> hard-to-maintain, hard-to-read classes definitions using this technique.
> Seems counter-productive.
>  
> 


Aye ... I'm a big fan of Factory designs, and nested-classes, but would typically not expose the inner class in that manner ~ would be exposed via an interface or something instead.

As I understand it, inner-classes (as a concept) are intended primarily as a convenient means of encapsualting specific internal functionality, for either handing off to a framework or for simplifying internal implementation detail. I can't recall reading /any/ papers or documents suggesting they should be made available as general-purpose public classes, and don't recall ever finding a need to do so. Of course, that's just my experience only.

Would be very interested to understand why it's needed in this case ...
July 31, 2006
Derek wrote:

> On Sun, 30 Jul 2006 21:55:59 +0200, Dawid Ciężarkiewicz wrote:
> 
>> Dawid Ciężarkiewicz wrote:
>>> In extremal situations you can even get something you can't compile in
>>> any way:
>>> http://d.puremagic.com/issues/show_bug.cgi?id=104
>> 
>> I mean:
>> http://d.puremagic.com/issues/show_bug.cgi?id=102
> 
> I don't understand this Dawid. It seems you are trying to use a nested class inside another class, and I'm sure you can't and shouldn't do that.
>
> I thought the purpose of nested classes was to restrict the scope of the nested class to its parent and thus trying to use it outside of the parent doesn't seem right to me.

Not right. Nested _static_ classes are just like all other classes. The only change is just namespace. BTW. I do want use them like that and personally I think it has many advantages.

But it's not about classes. It's about symbols used as types. This should make more sense to all unconvinced:

$ cat test1.d
import test2;

class X {
        Y.NY t;
        enum NX {
                BLA,
                BLA1
        }
}

$ cat test2.d
import test1;

class Y {
        X.NX nx;
        enum NY {
                FOO,
                BAR
        }
}

Is impossible to compile just like bug #102.
July 31, 2006
On Mon, 31 Jul 2006 09:22:26 +0200, Dawid Ciężarkiewicz wrote:

> Derek wrote:
> 
>> On Sun, 30 Jul 2006 21:55:59 +0200, Dawid Ciężarkiewicz wrote:
>> 
>>> Dawid Ciężarkiewicz wrote:
>>>> In extremal situations you can even get something you can't compile in
>>>> any way:
>>>> http://d.puremagic.com/issues/show_bug.cgi?id=104
>>> 
>>> I mean:
>>> http://d.puremagic.com/issues/show_bug.cgi?id=102
>> 
>> I don't understand this Dawid. It seems you are trying to use a nested class inside another class, and I'm sure you can't and shouldn't do that.
>>
>> I thought the purpose of nested classes was to restrict the scope of the nested class to its parent and thus trying to use it outside of the parent doesn't seem right to me.
> 
> Not right. Nested _static_ classes are just like all other classes. The only change is just namespace. BTW. I do want use them like that and personally I think it has many advantages.

Thank you Dawid for helping me to understand your reasoning. I'm still learning things too.

However, your response of "Not right." is a bit too restricting. From what you and others have mentioned, it seems that there are at least three purposes of nested classes ... to limit the scope, as a convenience to access parent data members, and to provide a namespace. Of course I can see now that 'static' nesting is just for namespace purposes.

However it still seems like a 'hack' to me and the issue of namespaces ought to be better handled by some more explicit mechanism rather than relying on some side-effect of D. But that is an argument for another day <g>.

> But it's not about classes. It's about symbols used as types. This should make more sense to all unconvinced:

I was totally aware of the issue with enums etc... as I keep bumping into it too. I just gave up and now use module namespaces for enums.

$ cat test1.d
import test2;
import yenum;

class X {
        yenum.NY t;
}

$ cat test2.d
import test1;
import xenum;
class Y {
        xenum.NX nx;
}

$ cat xenum.d
enum NX {
       BLA,
       BLA1
 }

$ cat yenum.d
enum NY {
      FOO,
      BAR
     }


-- 
Derek
(skype: derek.j.parnell)
Melbourne, Australia
"Down with mediocrity!"
31/07/2006 5:52:32 PM
July 31, 2006
Derek Parnell wrote:
>> But it's not about classes. It's about symbols used as types. This should make more sense to all unconvinced:
> 
> I was totally aware of the issue with enums etc... as I keep bumping into it too. I just gave up and now use module namespaces for enums.

Well - that suck :/ . You and me may live with such limitations. Public will probably hang D on nearby tree and goes back to C++/Java/other languages.