digitalmars.D - Once Again, Feature Request: Nested classes in separate scope
- downs (23/23) Nov 05 2007 Needed: a way to add a nested class to some other class without the
- Vladimir Panteleev (9/31) Nov 06 2007 s
- Vladimir Panteleev (6/13) Nov 06 2007 Why do you call it a "circular relation"? Foo's declaration or implement...
- downs (6/19) Nov 06 2007 See the example. I need a Foo that owns many Bar's, but each Bar can
- Steven Schveighoffer (34/56) Nov 06 2007 Given your example, the "ownership" of the Bars by Foo isn't really
- downs (5/12) Nov 06 2007 To be brutally honest, the ownership stuff was mostly
- downs (6/9) Nov 06 2007 Yes, but part of the point of the proposal is to avoid using the has-a
- Regan Heath (10/19) Nov 06 2007 Isn't this the same modal as you often see in UI code, where a window
- downs (12/37) Nov 06 2007 Fair.
- Regan Heath (35/45) Nov 06 2007 I'm not sure I understand the "seperate scope" requirement, what's wrong...
- downs (9/31) Nov 06 2007 That becomes a problem when you'd like to support many different types
- David Wilson (14/26) Nov 06 2007 At present this throws the error:
- downs (5/12) Nov 06 2007 I'd very happily settle for that, considering that what I really,
Needed: a way to add a nested class to some other class without the nested class having to be inside the scope of the outer class. I believe this to be important, because it would let us express the relation of "belongs-to", forming the symmetric opposite of "has-a". It came up in the context of user interfaces, where every Window belongs-to a WindowManager. And yes, I know you can give the Window class a reference to the WindowManager that controls it, but that feels unclean. It's like, "The WindowManager has many Windows, and each Window has the original WindowManager". The relations are screwed up. Syntax proposal (just an idea): class Foo { int e; this() { e=4; } } class Bar in Foo : Object { void test() { writefln(e); } } void main() { auto foo=new Foo; auto bar=foo.new Bar; // behaves like a nested class bar.test(); // prints 4 } Whaddya think? :) --downs
Nov 05 2007
On Tue, 06 Nov 2007 04:48:43 +0200, downs <default_357-line yahoo.de> wr= ote:Needed: a way to add a nested class to some other class without the nested class having to be inside the scope of the outer class. I believe this to be important, because it would let us express the relation of "belongs-to", forming the symmetric opposite of "has-a". It came up in the context of user interfaces, where every Window belongs-to a WindowManager. And yes, I know you can give the Window class a reference to the WindowManager that controls it, but that feel=sunclean. It's like, "The WindowManager has many Windows, and each Wind=owhas the original WindowManager". The relations are screwed up. Syntax proposal (just an idea): class Foo { int e; this() { e=3D4; } } class Bar in Foo : Object { void test() { writefln(e); } } void main() { auto foo=3Dnew Foo; auto bar=3Dfoo.new Bar; // behaves like a nested class bar.test(); // prints 4 } Whaddya think? :)I think this could be done with the announced "alias foo this;" syntax. (just declare a Foo in Bar and import its namespace) -- = Best regards, Vladimir mailto:thecybershadow gmail.com
Nov 06 2007
On Tue, 06 Nov 2007 12:11:04 +0200, downs <default_357-line yahoo.de> wrote:Vladimir Panteleev wrote:Why do you call it a "circular relation"? Foo's declaration or implementation is still Bar-free. And technically speaking, this is done in the same way - a nested class's "parent" class is nothing but a hidden member. -- Best regards, Vladimir mailto:thecybershadow gmail.comI think this could be done with the announced "alias foo this;" syntax. (just declare a Foo in Bar and import its namespace)Yes, but part of the point of the whole thing was to avoid declaring a Foo in Bar, because that implies a circular ownership relation. --downs
Nov 06 2007
Vladimir Panteleev wrote:On Tue, 06 Nov 2007 12:11:04 +0200, downs <default_357-line yahoo.de> wrote:See the example. I need a Foo that owns many Bar's, but each Bar can also access all methods of Foo - the idea is that the Bars can only exist in the _context_ of a Foo, which is I think what inner classes were supposed to do. Sorry if I'm misunderstanding it. --downs :)Vladimir Panteleev wrote:Why do you call it a "circular relation"? Foo's declaration or implementation is still Bar-free. And technically speaking, this is done in the same way - a nested class's "parent" class is nothing but a hidden member.I think this could be done with the announced "alias foo this;" syntax. (just declare a Foo in Bar and import its namespace)Yes, but part of the point of the whole thing was to avoid declaring a Foo in Bar, because that implies a circular ownership relation. --downs
Nov 06 2007
"downs" <default_357-line yahoo.de> wrote in message news:fgpev2$rl6$4 digitalmars.com...Vladimir Panteleev wrote:Given your example, the "ownership" of the Bars by Foo isn't really expressed. In your example, the Bars know about Foo, but Foo does not know about Bar. And it can't, because how can you compile code that would know about all possible objects that use it as context? So the statement that the Foo owns many Bars implies that the Foo must have an aggregate of Bars. That being said, I think you are getting stuck up on the point that if a class contains a member, it owns that member *and* all data pointed to by the member. This isn't necessarily true, and is defined by the programmer, not the compiler. What the class owns is a *reference*. Whether it owns the memory pointed to by the reference or not is entirely up to you. As for your example, I would rewrite it like this: class Foo { int e; this() { e=4; } } class Bar { // Bar does not own foo, it only references it Foo foo; this(Foo f) { foo = f; assert(foo !is null);} void test() { writefln(foo.e); } } void main() { auto foo=new Foo; auto bar=new Bar(foo); // behaves like a nested class bar.test(); // prints 4 } Then derived classes derive from Bar, and all is happy. It isn't possible to create a derivative of Bar without an instance of Foo. the only difference in code usage is the new statement, but it's not that different. Derivatives of Bar must use their foo by referencing the foo member, but I think that might be a Good Thing. -SteveOn Tue, 06 Nov 2007 12:11:04 +0200, downs <default_357-line yahoo.de> wrote:See the example. I need a Foo that owns many Bar's, but each Bar can also access all methods of Foo - the idea is that the Bars can only exist in the _context_ of a Foo, which is I think what inner classes were supposed to do. Sorry if I'm misunderstanding it. --downs :)Vladimir Panteleev wrote:Why do you call it a "circular relation"? Foo's declaration or implementation is still Bar-free. And technically speaking, this is done in the same way - a nested class's "parent" class is nothing but a hidden member.I think this could be done with the announced "alias foo this;" syntax. (just declare a Foo in Bar and import its namespace)Yes, but part of the point of the whole thing was to avoid declaring a Foo in Bar, because that implies a circular ownership relation. --downs
Nov 06 2007
Steven Schveighoffer wrote:That being said, I think you are getting stuck up on the point that if a class contains a member, it owns that member *and* all data pointed to by the member. This isn't necessarily true, and is defined by the programmer, not the compiler. What the class owns is a *reference*. Whether it owns the memory pointed to by the reference or not is entirely up to you.To be brutally honest, the ownership stuff was mostly retrojustification; what I was really after was the syntax candy :p Ah well. Can't have everything. --downs
Nov 06 2007
Vladimir Panteleev wrote:I think this could be done with the announced "alias foo this;" syntax. (just declare a Foo in Bar and import its namespace)Yes, but part of the point of the proposal is to avoid using the has-a relationship in situations where it's inadequate or flat out wrong (the Window doesn't own the WindowManager, it's the other way around). Sorry if I'm misunderstanding an OO concept here. --downs
Nov 06 2007
downs wrote:Vladimir Panteleev wrote:Isn't this the same modal as you often see in UI code, where a window "has a" parent window. The parent window could be said to own the child window but the child still "has a" parent. I'm not sure "has a" necessarily implies ownership, this may be the point which is bothering you? I have a home, but my landlord owns it. I have a job, but I dont own any shares in the compay. ... ReganI think this could be done with the announced "alias foo this;" syntax. (just declare a Foo in Bar and import its namespace)Yes, but part of the point of the proposal is to avoid using the has-a relationship in situations where it's inadequate or flat out wrong (the Window doesn't own the WindowManager, it's the other way around). Sorry if I'm misunderstanding an OO concept here.
Nov 06 2007
Regan Heath wrote:downs wrote:Fair. Okay, let's drop the ownership debate and reformulate the problem to expressing that class Bar exists in the _context_ of class Foo. I agree that this relationship could be modelled by "class Foo { Bar context; alias context this; " as proposed before, but isn't this exactly what nested classes are supposed to be? Things that only exist in the context of something else? I simply think it would be better to extend this existing feature to allow Foo to be in a separate scope from Bar, instead of using what essentially amounts to a workaround. Nonetheless, thanks for your reply. :) --downsVladimir Panteleev wrote:Isn't this the same modal as you often see in UI code, where a window "has a" parent window. The parent window could be said to own the child window but the child still "has a" parent. I'm not sure "has a" necessarily implies ownership, this may be the point which is bothering you? I have a home, but my landlord owns it. I have a job, but I dont own any shares in the compay. ... ReganI think this could be done with the announced "alias foo this;" syntax. (just declare a Foo in Bar and import its namespace)Yes, but part of the point of the proposal is to avoid using the has-a relationship in situations where it's inadequate or flat out wrong (the Window doesn't own the WindowManager, it's the other way around). Sorry if I'm misunderstanding an OO concept here.
Nov 06 2007
downs wrote:Okay, let's drop the ownership debate and reformulate the problem to expressing that class Bar exists in the _context_ of class Foo. I agree that this relationship could be modelled by "class Foo { Bar context; alias context this; " as proposed before, but isn't this exactly what nested classes are supposed to be? Things that only exist in the context of something else? I simply think it would be better to extend this existing feature to allow Foo to be in a separate scope from Bar, instead of using what essentially amounts to a workaround. Nonetheless, thanks for your reply. :) --downsI'm not sure I understand the "seperate scope" requirement, what's wrong with: --[windowmanager.d]-- module windowmanager; class WindowManager { class Window { private this() { } } Window[] children; Window createWindow() { children ~= new Window(); return children[$-1]; } } --[windowmanager_main.d]-- module windowmanager_main; import windowmanager; void main() { auto m = new WindowManager(); auto w1 = m.createWindow(); auto w2 = m.createWindow(); auto w3 = m.new Window(); //this is not accessible } Is the problem that you need to allow users to derive custom window types from Window? I'm not sure if it's possible to derive from an inner class or what the syntax would be if it was... Regan
Nov 06 2007
Regan Heath wrote:I'm not sure I understand the "seperate scope" requirement, what's wrong with: --[windowmanager.d]--[snip]--[windowmanager_main.d]-- module windowmanager_main; import windowmanager; void main() { auto m = new WindowManager(); auto w1 = m.createWindow(); auto w2 = m.createWindow(); auto w3 = m.new Window(); //this is not accessible }That becomes a problem when you'd like to support many different types of windows and, well, don't want them _all in one file_.Is the problem that you need to allow users to derive custom window types from Window?Well, that too :pI'm not sure if it's possible to derive from an inner class or what the syntax would be if it was...I don't see why it shouldn't be, theoretically. Though I also don't know what the syntax is (or would be). It doesn't seem to be possible at all right now.Regan--downs
Nov 06 2007
On 11/6/07, downs <default_357-line yahoo.de> wrote:That becomes a problem when you'd like to support many different types of windows and, well, don't want them _all in one file_.At present this throws the error: a.d(11): class a.Inner2 super class Inner is nested within Outer, not a If this was made legal, would you still have a problem? Conceptually, it seems fine to me that a subclass of an inner class should inherit its access to the outer class. Certainly if this wasn't intended, a class designer could specify "final" on the original inner class. class WindowManager { class Window {} } class ToolWindow : WindowManager.Window { } (BTW: I thought window managers governed windows, not owned them? Also, a button is a kind of window :)Is the problem that you need to allow users to derive custom window types from Window?Well, that too :pI'm not sure if it's possible to derive from an inner class or what the syntax would be if it was...I don't see why it shouldn't be, theoretically. Though I also don't know what the syntax is (or would be). It doesn't seem to be possible at all right now.Getting the existing rule relaxed might be easier than getting new syntax implemented. David.Regan--downs
Nov 06 2007
David Wilson wrote:Getting the existing rule relaxed might be easier than getting new syntax implemented. David.I'd very happily settle for that, considering that what I really, honestly wanted was the syntax candy of a nested class without the same-fileness this currently entails. --downs
Nov 06 2007