www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Advantages of nested aggregates?

reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
DMD 0.119 makes it illegal for an inner aggregate (such as a nested class or 
struct) to directly access the member variables and functions of the outer 
aggregate.  As one of my projects depends heavily on the old behavior, and 
because there does not seem to be a simple or elegant solution to the 
problem (I now must initialize a "that" pointer for every inner class that 
points to the instance of the outer class to which is belongs and refer to 
all outer members through the "that" pointer.. absurd, as there is no other 
purpose for the inner class than to function as a helper to the outer 
class), I now ask - is there any reason for this "fixed" behavior?

Namely, what advantages does disallowing access to outer members offer? 
What horrible bugs does it prevent?

Walter stated in his reply to me on the announcements board that D's nested 
aggregates do not behave like Java's.  My problem is that I don't see what's 
wrong with how Java's nested aggregates work, as they seem to be more useful 
than the new D behavior.

It seems that there is no longer much of an advantage to even using a nested 
aggregate anymore.  There don't seem to be any abilities that nested 
aggregates provide that would be impossible with a separate aggregate.

Thoughts, opinions? 
Mar 21 2005
next sibling parent Ant <Ant_member pathlink.com> writes:
In article <d1nhqh$tq8$1 digitaldaemon.com>, Jarrett Billingsley says...
DMD 0.119 makes it illegal for an inner aggregate (such as a nested class or 
struct) to directly access the member variables and functions of the outer 
aggregate.  As one of my projects depends heavily on the old behavior, and 
because there does not seem to be a simple or elegant solution to the 
problem (I now must initialize a "that" pointer for every inner class that 
points to the instance of the outer class to which is belongs and refer to 
all outer members through the "that" pointer.. absurd, as there is no other 
purpose for the inner class than to function as a helper to the outer 
class), I now ask - is there any reason for this "fixed" behavior?

Namely, what advantages does disallowing access to outer members offer? 
What horrible bugs does it prevent?

Walter stated in his reply to me on the announcements board that D's nested 
aggregates do not behave like Java's.  My problem is that I don't see what's 
wrong with how Java's nested aggregates work, as they seem to be more useful 
than the new D behavior.

It seems that there is no longer much of an advantage to even using a nested 
aggregate anymore.  There don't seem to be any abilities that nested 
aggregates provide that would be impossible with a separate aggregate.

Thoughts, opinions? 
I'm with you. But the 'Old behaviour' is not that old as I never experienced that. I asked for inner classes before, never got Walter's attention. I also create a 'that' pointer to the outer class. Ant
Mar 21 2005
prev sibling next sibling parent reply Derek Parnell <derek psych.ward> writes:
On Mon, 21 Mar 2005 17:31:16 -0500, Jarrett Billingsley wrote:

 DMD 0.119 makes it illegal for an inner aggregate (such as a nested class or 
 struct) to directly access the member variables and functions of the outer 
 aggregate.  As one of my projects depends heavily on the old behavior, and 
 because there does not seem to be a simple or elegant solution to the 
 problem (I now must initialize a "that" pointer for every inner class that 
 points to the instance of the outer class to which is belongs and refer to 
 all outer members through the "that" pointer.. absurd, as there is no other 
 purpose for the inner class than to function as a helper to the outer 
 class), I now ask - is there any reason for this "fixed" behavior?
 
 Namely, what advantages does disallowing access to outer members offer? 
 What horrible bugs does it prevent?
 
 Walter stated in his reply to me on the announcements board that D's nested 
 aggregates do not behave like Java's.  My problem is that I don't see what's 
 wrong with how Java's nested aggregates work, as they seem to be more useful 
 than the new D behavior.
 
 It seems that there is no longer much of an advantage to even using a nested 
 aggregate anymore.  There don't seem to be any abilities that nested 
 aggregates provide that would be impossible with a separate aggregate.
I'm not familiar with the notion of nested classes. What problem does nested classes solve? I understand what they are, I just don't know why would one bother. How does Java's class nesting help a coder? That is not a rhetorical question, as I really have no experience with them and I'd like to understand what all the fuss is about. -- Derek Melbourne, Australia 22/03/2005 10:23:16 AM
Mar 21 2005
next sibling parent reply "Ben Hinkle" <ben.hinkle gmail.com> writes:
 It seems that there is no longer much of an advantage to even using a 
 nested
 aggregate anymore.  There don't seem to be any abilities that nested
 aggregates provide that would be impossible with a separate aggregate.
The old behavior was a bug - D's nested aggregates were only like Java's inner classes in the special case when there weren't any data members in the inner class (if I understand correctly). Java's inner classes are useful and so I hope some day D will get them. It takes a while to grok the Java behavior and it can be tricky sorting out the references and making sure you don't leak anything by having these hidden references (it happens).
 I'm not familiar with the notion of nested classes. What problem does
 nested classes solve? I understand what they are, I just don't know why
 would one bother. How does Java's class nesting help a coder? That is not 
 a
 rhetorical question, as I really have no experience with them and I'd like
 to understand what all the fuss is about.
Inner classes were added to Java to make two things easier 1) hooking up listeners 2) make iterators (or classes that are roughly like iterators in scope) easier to write Iterators become easier to write because each iterator implicitly has a pointer to the container and can query state in the container without forcing the author to explicitly carry around and manage a reference to it. Hooking up listeners became easier because they also introduced anonymous inner classes: button.addActionListener( new ActionListener() { void actionPerformed(ActionEvent ev) { .. do stuff with enclosing object - not the anonymous object... } }); -Ben
Mar 21 2005
next sibling parent Derek Parnell <derek psych.ward> writes:
On Mon, 21 Mar 2005 19:11:06 -0500, Ben Hinkle wrote:

 It seems that there is no longer much of an advantage to even using a 
 nested
 aggregate anymore.  There don't seem to be any abilities that nested
 aggregates provide that would be impossible with a separate aggregate.
The old behavior was a bug - D's nested aggregates were only like Java's inner classes in the special case when there weren't any data members in the inner class (if I understand correctly). Java's inner classes are useful and so I hope some day D will get them. It takes a while to grok the Java behavior and it can be tricky sorting out the references and making sure you don't leak anything by having these hidden references (it happens).
 I'm not familiar with the notion of nested classes. What problem does
 nested classes solve? I understand what they are, I just don't know why
 would one bother. How does Java's class nesting help a coder? That is not 
 a
 rhetorical question, as I really have no experience with them and I'd like
 to understand what all the fuss is about.
Inner classes were added to Java to make two things easier 1) hooking up listeners 2) make iterators (or classes that are roughly like iterators in scope) easier to write Iterators become easier to write because each iterator implicitly has a pointer to the container and can query state in the container without forcing the author to explicitly carry around and manage a reference to it. Hooking up listeners became easier because they also introduced anonymous inner classes: button.addActionListener( new ActionListener() { void actionPerformed(ActionEvent ev) { .. do stuff with enclosing object - not the anonymous object... } }); -Ben
Clear as mud ;-) Sorry, but that didn't help me at all. Maybe this is just a problem that I've not had to deal with yet, or solved it in another manner that I'm not aware of. Anyhow, I can't see that I need to get any deeper for now. Thanks anyway. -- Derek Melbourne, Australia 22/03/2005 11:17:02 AM
Mar 21 2005
prev sibling parent reply "Walter" <newshound digitalmars.com> writes:
"Ben Hinkle" <ben.hinkle gmail.com> wrote in message
news:d1nnqi$13h5$1 digitaldaemon.com...
 It seems that there is no longer much of an advantage to even using a
 nested
 aggregate anymore.  There don't seem to be any abilities that nested
 aggregates provide that would be impossible with a separate aggregate.
The old behavior was a bug - D's nested aggregates were only like Java's inner classes in the special case when there weren't any data members in
the
 inner class (if I understand correctly). Java's inner classes are useful
and
 so I hope some day D will get them. It takes a while to grok the Java
 behavior and it can be tricky sorting out the references and making sure
you
 don't leak anything by having these hidden references (it happens).
I believe that D's delegates cover what Java inner classes did.
Mar 21 2005
parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Walter" <newshound digitalmars.com> wrote in message 
news:d1nt2m$17su$1 digitaldaemon.com...
 I believe that D's delegates cover what Java inner classes did.
Oh, would I be enlightened to see how so. While you're at it, mind explaining even allowing inner classes anymore if they serve no special purpose?
Mar 21 2005
parent reply "Ben Hinkle" <ben.hinkle gmail.com> writes:
"Jarrett Billingsley" <kb3ctd2 yahoo.com> wrote in message 
news:d1o0aa$1bd3$1 digitaldaemon.com...
 "Walter" <newshound digitalmars.com> wrote in message 
 news:d1nt2m$17su$1 digitaldaemon.com...
 I believe that D's delegates cover what Java inner classes did.
Oh, would I be enlightened to see how so.
I can see how they'd cover the case of registering listeners (register a delegate instead) but if you are saying delegates don't cover the case when you want a "dependent data structure" then I'd have to agree with you. For those cases in D you have to manage the reference to the primary data structure explicitly.
 While you're at it, mind explaining even allowing inner classes anymore if 
 they serve no special purpose?
I guess name scoping would be pretty much the only reason. Plus if the language spec says a class or struct can contain other type definitions then why explicitly exclude class or struct definitions? In some sense the current behavior is cleaner from a language viewpoint since all the type definitions in a class or struct body are treated the same way.
Mar 21 2005
parent reply "Walter" <newshound digitalmars.com> writes:
"Ben Hinkle" <ben.hinkle gmail.com> wrote in message
news:d1o2i7$1dhi$1 digitaldaemon.com...
 "Jarrett Billingsley" <kb3ctd2 yahoo.com> wrote in message
 news:d1o0aa$1bd3$1 digitaldaemon.com...
 "Walter" <newshound digitalmars.com> wrote in message
 news:d1nt2m$17su$1 digitaldaemon.com...
 I believe that D's delegates cover what Java inner classes did.
Oh, would I be enlightened to see how so.
I can see how they'd cover the case of registering listeners (register a delegate instead)
As I understand it, that case was the motivation behind Java's inner classes.
 but if you are saying delegates don't cover the case when
 you want a "dependent data structure" then I'd have to agree with you. For
 those cases in D you have to manage the reference to the primary data
 structure explicitly.
That's right.
 While you're at it, mind explaining even allowing inner classes anymore
if
 they serve no special purpose?
I guess name scoping would be pretty much the only reason.
Yes, but it's a pretty big reason. For example, the internal implementation of a class may need a 'helper struct' that is of only use for that implementation, in which case there is no need to expose the helper struct definition outside of that class. The idea is that each definition of every type should be visible in as narrow a scope as possible.
 Plus if the
 language spec says a class or struct can contain other type definitions
then
 why explicitly exclude class or struct definitions? In some sense the
 current behavior is cleaner from a language viewpoint since all the type
 definitions in a class or struct body are treated the same way.
Yes. Making the rules as consistent as possible makes the language easier to learn, and more sensible.
Mar 22 2005
next sibling parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Walter" <newshound digitalmars.com> wrote in message 
news:d1oo33$23vv$1 digitaldaemon.com...
 but if you are saying delegates don't cover the case when
 you want a "dependent data structure" then I'd have to agree with you. 
 For
 those cases in D you have to manage the reference to the primary data
 structure explicitly.
That's right.
I'm asking why it has to be that way. Why can't we have inner classes? They surely have many more uses than just for creating event listeners!
 While you're at it, mind explaining even allowing inner classes anymore
if
 they serve no special purpose?
I guess name scoping would be pretty much the only reason.
Yes, but it's a pretty big reason. For example, the internal implementation of a class may need a 'helper struct' that is of only use for that implementation, in which case there is no need to expose the helper struct definition outside of that class. The idea is that each definition of every type should be visible in as narrow a scope as possible.
Why doesn't a helper struct have access to the outer class then? If it serves no other purpose than to assist the outer class, why bother making the data inaccessible except through a reference to the outer class to which the inner class belongs?
 Plus if the
 language spec says a class or struct can contain other type definitions
then
 why explicitly exclude class or struct definitions? In some sense the
 current behavior is cleaner from a language viewpoint since all the type
 definitions in a class or struct body are treated the same way.
Yes. Making the rules as consistent as possible makes the language easier to learn, and more sensible.
Again I present the comparison to nested functions. In my mind, a nested function serves the same purpose as a nested class should - generally a small helper which you would not like to be exposed to the rest of the program. Nested functions are allowed to access the variables of the enclosing function, as it eliminates the need to redundantly pass several parameters over and over, and because the nested functions usually do something to affect the variables in the outer function. Shouldn't a nested class function the same way? Please respond, Walter; I'm feeling a bit offended that you have yet to respond _directly_ to any of my questions!
Mar 22 2005
parent reply "Walter" <newshound digitalmars.com> writes:
"Jarrett Billingsley" <kb3ctd2 yahoo.com> wrote in message
news:d1q3go$jrb$1 digitaldaemon.com...
 "Walter" <newshound digitalmars.com> wrote in message
 news:d1oo33$23vv$1 digitaldaemon.com...
 but if you are saying delegates don't cover the case when
 you want a "dependent data structure" then I'd have to agree with you.
 For
 those cases in D you have to manage the reference to the primary data
 structure explicitly.
That's right.
I'm asking why it has to be that way. Why can't we have inner classes? They surely have many more uses than just for creating event listeners!
I agree there are surely more uses for them. It's a cost benefit thing. Is there enough of a use to justify setting something else aside to implement it? Are those other uses hard or easy to achieve using other, existing methods?
 Why doesn't a helper struct have access to the outer class then?  If it
 serves no other purpose than to assist the outer class, why bother making
 the data inaccessible except through a reference to the outer class to
which
 the inner class belongs?
Implementing it would require a hidden 'this' member added to each inner struct. This has to be initialized at runtime, some syntax has to be invented to do it, there's a runtime time and size cost. Not that these are terribly onerous, but the feature doesn't come for free, and will weigh down the programmer who wants a 'lightweight' nested struct instead.
 Again I present the comparison to nested functions.  In my mind, a nested
 function serves the same purpose as a nested class should - generally a
 small helper which you would not like to be exposed to the rest of the
 program.  Nested functions are allowed to access the variables of the
 enclosing function, as it eliminates the need to redundantly pass several
 parameters over and over, and because the nested functions usually do
 something to affect the variables in the outer function.  Shouldn't a
nested
 class function the same way?
You could look at it that way. I've seen inner classes in Java used as rather complicated ways to achieve what can be done with simpler nested functions. Delegates are also much simpler than inner classes. Take those two together, and inner classes left me with the feeling that they were the wrong solution.
Mar 22 2005
next sibling parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Walter" <newshound digitalmars.com> wrote in message 
news:d1qdqd$ug6$1 digitaldaemon.com...
 I agree there are surely more uses for them. It's a cost benefit thing. Is
 there enough of a use to justify setting something else aside to implement
 it? Are those other uses hard or easy to achieve using other, existing
 methods?
 Implementing it would require a hidden 'this' member added to each inner
 struct. This has to be initialized at runtime, some syntax has to be
 invented to do it, there's a runtime time and size cost. Not that these 
 are
 terribly onerous, but the feature doesn't come for free, and will weigh 
 down
 the programmer who wants a 'lightweight' nested struct instead.
Which is essentially what I have to do now, but manually. I suppose an "inner" keyword or similar could be introduced, though I'm not sure introducing something like that so late in the game is such a good idea. Then again, it's not a very complicated feature. It's certainly possible to "emulate" inner classes with user-written code as of now - it's just that it's a real hassle to maintain.
 You could look at it that way. I've seen inner classes in Java used as
 rather complicated ways to achieve what can be done with simpler nested
 functions. Delegates are also much simpler than inner classes. Take those
 two together, and inner classes left me with the feeling that they were 
 the
 wrong solution.
I suppose, as Charles Hixson said in the other reply to your post, it could be argued either way.
Mar 22 2005
parent "Ben Hinkle" <bhinkle mathworks.com> writes:
"Jarrett Billingsley" <kb3ctd2 yahoo.com> wrote in message 
news:d1qlfe$1556$1 digitaldaemon.com...
 "Walter" <newshound digitalmars.com> wrote in message 
 news:d1qdqd$ug6$1 digitaldaemon.com...
 I agree there are surely more uses for them. It's a cost benefit thing. 
 Is
 there enough of a use to justify setting something else aside to 
 implement
 it? Are those other uses hard or easy to achieve using other, existing
 methods?
 Implementing it would require a hidden 'this' member added to each inner
 struct. This has to be initialized at runtime, some syntax has to be
 invented to do it, there's a runtime time and size cost. Not that these 
 are
 terribly onerous, but the feature doesn't come for free, and will weigh 
 down
 the programmer who wants a 'lightweight' nested struct instead.
Which is essentially what I have to do now, but manually. I suppose an "inner" keyword or similar could be introduced, though I'm not sure introducing something like that so late in the game is such a good idea. Then again, it's not a very complicated feature. It's certainly possible to "emulate" inner classes with user-written code as of now - it's just that it's a real hassle to maintain.
What you need is a ... naming convention! Yes, and boy oh boy do I have a naming convention for you. Get ready ladies and gentleman for the naming convention that will knock your socks off. This little doozie is fresh from another thread we recently had but this time it has found its true home. Forget about implicit references or clumsy names like "outer" or "outerthis". What we need is something short and sweet. That might sound familiar so I'm just gonna paste some code that illustrates the idea. You're gonna love it, I promise ;-) struct A { int x; char[] str; struct B { // the helper struct A*_; // the magic _ strikes again! void foo() { writefln("%d",_.x); // read outer field _.str = "hello"; // write outer field } } B make() { B b; b._ = this; // initialize the outer ref return b; } } int main() { A a; a.x = 10; A.B b = a.make; b.foo(); writefln("%s",a.str); return 0; }
Mar 23 2005
prev sibling next sibling parent xs0 <xs0 xs0.com> writes:
Why doesn't a helper struct have access to the outer class then?  If it
serves no other purpose than to assist the outer class, why bother making
the data inaccessible except through a reference to the outer class to
which the inner class belongs?
Implementing it would require a hidden 'this' member added to each inner struct. This has to be initialized at runtime, some syntax has to be invented to do it, there's a runtime time and size cost. Not that these are terribly onerous, but the feature doesn't come for free, and will weigh down the programmer who wants a 'lightweight' nested struct instead.
In Java, you can have a "normal" inner class (with the reference to outer object), or a "static" inner class (which doesn't have it). I think this could even be determined automatically.. as for syntax, "this" is the inner object, while OuterClassName.this refers to the outer object. I think that is all that's needed..
Again I present the comparison to nested functions.  In my mind, a nested
function serves the same purpose as a nested class should - generally a
small helper which you would not like to be exposed to the rest of the
program.  Nested functions are allowed to access the variables of the
enclosing function, as it eliminates the need to redundantly pass several
parameters over and over, and because the nested functions usually do
something to affect the variables in the outer function.  Shouldn't a
nested
class function the same way?
You could look at it that way. I've seen inner classes in Java used as rather complicated ways to achieve what can be done with simpler nested functions. Delegates are also much simpler than inner classes. Take those two together, and inner classes left me with the feeling that they were the wrong solution.
I agree delegates are really neat, but sometimes you want to handle an interface bigger than a single function, in which case D makes things somewhat complicated. I mean, this is obviously something that can be coded manually, but is much easier, if the language supports it. The Java folks will also be somewhat disappointed that this functionality is missing, especially because it's used so extensively in Java. When I finally switch to D, I'll also miss anonymous classes. I find it extremely useful (in Java) that it's possible to implement/override functionality without polluting the namespace with otherwise useless stuff, and the code is actually there where it's used, not in some other place.. xs0
Mar 23 2005
prev sibling parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Walter" <newshound digitalmars.com> wrote in message 
news:d1qdqd$ug6$1 digitaldaemon.com...
 You could look at it that way. I've seen inner classes in Java used as
 rather complicated ways to achieve what can be done with simpler nested
 functions. Delegates are also much simpler than inner classes. Take those
 two together, and inner classes left me with the feeling that they were 
 the
 wrong solution.
I've found another inherent problem with the current manual method of making an "inner class." You cannot override the inner class's functions. Say you have class A, which has an inner class called IC. IC has a method. Then say you have class B which derives from A. If you then have an inner class IC in B, and "override" the function that was declared in A's IC, it is not really overriding, even if B's IC derives from A's IC. That is, if you make a new B, cast it to an A, and call the method, it will call A's method, not B's. This surely isn't consistent with the idea of polymorphism. import std.stdio; class A { public: this() { ic=new IC; ic.that=this; } class IC { int x() { return 10; } A that; } IC ic; private: int _x; } class B : A { this() { ic=new IC; ic.that=this; } class IC : A.IC { int x() { return 20; } A that; } IC ic; } void main() { B b=new B; writefln(b.ic.x); A a=cast(A)b; writefln(a.ic.x); } If the idea of an inner class were part of the language, the compiler would be able to see that I am trying to override the x() method, and would create the appropriate vtable. Is this convincing yet?
Mar 24 2005
parent "Ben Hinkle" <bhinkle mathworks.com> writes:
 If the idea of an inner class were part of the language, the compiler 
 would be able to see that I am trying to override the x() method, and 
 would create the appropriate vtable.

 Is this convincing yet?
What you are seeing isn't a bug and I wouldn't want it as a feature. You have two "ic" fields - one for the A.IC you allocate in A.this and the other for B.IC you allocate in B.this. When you cast to A you start using A.ic. I don't see what this has to do with Java's inner class behavior since the inner class should be the one with a reference to the outer class, not vice versa. If anything it would be nice to get a warning the B.ic is shadowing A.ic.
Mar 24 2005
prev sibling parent Charles Hixson <charleshixsn earthlink.net> writes:
Walter wrote:
 "Ben Hinkle" <ben.hinkle gmail.com> wrote in message
 news:d1o2i7$1dhi$1 digitaldaemon.com...
 
"Jarrett Billingsley" <kb3ctd2 yahoo.com> wrote in message
news:d1o0aa$1bd3$1 digitaldaemon.com...

"Walter" <newshound digitalmars.com> wrote in message
news:d1nt2m$17su$1 digitaldaemon.com...

I believe that D's delegates cover what Java inner classes did.
Oh, would I be enlightened to see how so.
I can see how they'd cover the case of registering listeners (register a delegate instead)
As I understand it, that case was the motivation behind Java's inner classes.
but if you are saying delegates don't cover the case when
you want a "dependent data structure" then I'd have to agree with you. For
those cases in D you have to manage the reference to the primary data
structure explicitly.
... Yes. Making the rules as consistent as possible makes the language easier to learn, and more sensible.
As far as consistency rules, the visibility of external names in the containing block goes back as far as Pascall, and I never heard anyone call it inconsistent. Now it's true that what Pascal had were internal functions rather than internal classes, but the analogy is straightforward. (This is not an argument that you SHOULD implement them, but rather that if you want to claim inconsistency, you should delineate in what way you consider it inconsistent.) OTOH: Different languages have different scoping rules. If you doubt this, look at assembler and Python! There are choices that must be made when one is defining the language, and it is perhaps less important exactly which choice is made than that the choice is explicitly spelled out. A choice that says that code inside a parameterized block cannot see non-publically visible code outside the block is certainly reasonable and consistent. (But what about the code within the blocks of for statements? Perhaps that's not the desired behavior.) Coming up with a clear statement of the scoping rules has been a headache as far back as Algol. It's nearly bad enough that one could say "The clearest set of rules is the best!", unfortunately, usefulness prevents that choice. D's visibility rules are fairly straightforward. This bit about internal visibility of class variables is one of the few odd places where the rules aren't immediately obvious. Either choice can be defended.
Mar 22 2005
prev sibling next sibling parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Derek Parnell" <derek psych.ward> wrote in message 
news:12n1f4rccbqpu$.oitka3ycj5ox.dlg 40tude.net...
 I'm not familiar with the notion of nested classes. What problem does
 nested classes solve? I understand what they are, I just don't know why
 would one bother. How does Java's class nesting help a coder? That is not 
 a
 rhetorical question, as I really have no experience with them and I'd like
 to understand what all the fuss is about.
As a somewhat more.. generic explanation ;) Think of when you use nested functions. That's pretty much how you use a nested class. When you want a second, smaller, helper class, but not necessarily one that can be accessed outside the enclosing class, and when you don't want to have to worry data hiding. They're like friend classes, but on an even closer level - a nested class simply defines a sub-level of functionality within a larger class, and would probably be useless if it weren't part of ther larger class. I didn't realize that the "old" behavior was broken as well -- well, at least "broken" in the wrong way. Instead of making all outer members available, it was decided that _no_ outer members should be accessible.. which doesn't make much sense.. I just never ran across the other situation, where the nested class had members.
Mar 21 2005
parent reply "Charlie Patterson" <charliep1 excite.com> writes:
Maybe I'm issing something, but a class, even an "internal" one, should get 
all of it's ins and outs explicitly.  That, to me, is the idea of a class --  
self-contained.  If you have one class that magically gets at other classes 
variables, even "external" ones, it seems like a design issue.  Perhaps a 
concrete example would help.

My two cents is that "everything is an object" Java was a great ideology to 
get people excited but the problems with this approach start breaking 
through once you have callbacks, globals, and other issues.

"Jarrett Billingsley" <kb3ctd2 yahoo.com> wrote in message 
news:d1nrue$170l$1 digitaldaemon.com...
 Think of when you use nested functions.  That's pretty much how you use a 
 nested class.  When you want a second, smaller, helper class, but not 
 necessarily one that can be accessed outside the enclosing class, and when 
 you don't want to have to worry data hiding.  They're like friend classes, 
 but on an even closer level - a nested class simply defines a sub-level of 
 functionality within a larger class, and would probably be useless if it 
 weren't part of ther larger class.
 
Mar 23 2005
parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Charlie Patterson" <charliep1 excite.com> wrote in message 
news:d1sdnd$31jf$1 digitaldaemon.com...
 Maybe I'm issing something, but a class, even an "internal" one, should 
 get all of it's ins and outs explicitly.  That, to me, is the idea of a 
 class --  self-contained.  If you have one class that magically gets at 
 other classes variables, even "external" ones, it seems like a design 
 issue.  Perhaps a concrete example would help.
And it's not possible to have an exception to the rule, where you can have classes which do access each others' internals? Honestly, would you create five small, otherwise useless helper functions for a larger functions and declare them outside of the large function, free for any other function in the same module to use? Allowing inner classes only serves to extend the idea of classes being self-contained. You wouldn't want to expose those small and otherwise useless functions to the rest of the module; inner classes should serve the same purpose: hiding functionality that you don't want to be accessed outside the class.
Mar 23 2005
parent "Charlie Patterson" <charliep1 excite.com> writes:
"Jarrett Billingsley" <kb3ctd2 yahoo.com> wrote in message 
news:d1slfq$87k$1 digitaldaemon.com...
 "Charlie Patterson" <charliep1 excite.com> wrote in message 
 news:d1sdnd$31jf$1 digitaldaemon.com...
 Maybe I'm issing something, but a class, even an "internal" one, should 
 get all of it's ins and outs explicitly.  That, to me, is the idea of a 
 class --  self-contained.  If you have one class that magically gets at 
 other classes variables, even "external" ones, it seems like a design 
 issue.  Perhaps a concrete example would help.
And it's not possible to have an exception to the rule, where you can have classes which do access each others' internals?
If you tried to wrap every exception into the language, then it would be huge. At some point, exceptions are exceptions and require programming the hard way.
 Honestly, would you create five small, otherwise useless helper functions 
 for a larger functions and declare them outside of the large function, 
 free for any other function in the same module to use?
Hopefully not, but functions are different from classes. They aren't "active" and self-contained. I think that, if there are sub-classes, which is fine by me, there shouldn't be calls to the "external" classes variables because it defies the class ideal. If your external class "has a" version of an internal class or two, it should treat it like any ordinary class that it would own, which assumes the internal class won't be mucking with the external one's stuff. In Java, (and I've only read it, not used it) you can see the seems splitting around AWT. I'm assuming this problem is about getting functionality similar to the Java internal classes? Because Java insists everything is a class, they either needed you to declare a class for each button, modifying the behaviour in that subclass, all to create one instance; or they needed a callback. But callbacks are functions, not classes, and everything in Java is a class, so they hacked up a way to wrap a function in a class without it being too obnoxious. Without more concrete information, it is not obvious why you need it like Java needed it. And I really don't see why an internal class should see the external vars.
Mar 23 2005
prev sibling parent Charles Hixson <charleshixsn earthlink.net> writes:
Derek Parnell wrote:
 On Mon, 21 Mar 2005 17:31:16 -0500, Jarrett Billingsley wrote:
 ...
 
 I'm not familiar with the notion of nested classes. What problem does
 nested classes solve? I understand what they are, I just don't know why
 would one bother. How does Java's class nesting help a coder? That is not a
 rhetorical question, as I really have no experience with them and I'd like
 to understand what all the fuss is about.
 
Obviously one can't produce a D example, but here's an example of the use in Python. I wouldn't say that the use need is critical, at least in a language that has private-to-file declarations, but they can certainly be convenient at times. (For me this is *rare* times, but occasionally.) P.S.: I'm certainly not claiming this as an example of elegant coding, but it does illustrate a use for internal classes.
Mar 22 2005
prev sibling parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Jarrett Billingsley wrote:
 DMD 0.119 makes it illegal for an inner aggregate (such as a nested class or 
 struct) to directly access the member variables and functions of the outer 
 aggregate.  As one of my projects depends heavily on the old behavior, and 
 because there does not seem to be a simple or elegant solution to the 
 problem
In that case, you were writing invalid code in the first place.
 (I now must initialize a "that" pointer for every inner class that 
 points to the instance of the outer class to which is belongs and refer to 
 all outer members through the "that" pointer.. 
<snip> D doesn't have inner classes as such. If it ever appeared to have them, it was only a result of a bug. In D, a nested class is simply a class defined in the scope of another. An object of one doesn't belong to any object of the outer class, so it has no 'outer this' pointer. If it ever worked to an extent, I can only see it being when the 'inner' class function is inlined and called from a method of the outer class. Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Mar 22 2005
parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Stewart Gordon" <smjg_1998 yahoo.com> wrote in message 
news:d1po8g$8b8$1 digitaldaemon.com...

 In that case, you were writing invalid code in the first place.
Which I didn't know was invalid, as the spec mentions nothing about access rights of nested aggregates. In fact, I can't even find any mention of nested aggregates in the spec, save for the mention of converting over from C. I figured that what was happening was the correct behavior.
 D doesn't have inner classes as such.  If it ever appeared to have them, 
 it was only a result of a bug.
I know that now; what I'm asking is WHY it doesn't have inner classes, as they seem to be a lot more useful than what D has now!
 In D, a nested class is simply a class defined in the scope of another. An 
 object of one doesn't belong to any object of the outer class, so it has 
 no 'outer this' pointer.
Again, I'm asking how this makes practical sense. What is the point of having nested aggregates if they offer nothing that couldn't be done with a separate outer class?
Mar 22 2005