www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Lack of `outer` keyword makes inner class dup implossible

reply S. <S._member pathlink.com> writes:
It seems that because inner classes lack an `outer` keyword it is impossible for
them to create a new instance for the purpose of COW when operators like opCom
are called...

sudoku.d(318): outer class Foobar 'this' needed to 'new' nested class BarBar
Jul 14 2006
parent reply "Derek Parnell" <derek psych.ward> writes:
On Sat, 15 Jul 2006 06:20:12 +1000, S. <S._member pathlink.com> wrote:

 It seems that because inner classes lack an `outer` keyword it is  
 impossible for
 them to create a new instance for the purpose of COW when operators like  
 opCom
 are called...

 sudoku.d(318): outer class Foobar 'this' needed to 'new' nested class  
 BarBar

Excuse my ignorance, but what does an inner class provide that other alternatives can't? -- Derek Parnell Melbourne, Australia
Jul 14 2006
parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Derek Parnell" <derek psych.ward> wrote in message 
news:op.tcpklel16b8z09 ginger.vic.bigpond.net.au...

 Excuse my ignorance, but what does an inner class provide that other 
 alternatives can't?

Well, what does a nested function provide that a separate, external function doesn't? - Encapsulation - Access to outer variables - Is a Cool Thing (TM) ;) Pretty much the same thing applies to inner classes, although I'll grant you, I don't use inner classes as much as nested functions.
Jul 14 2006
next sibling parent reply "Derek Parnell" <derek psych.ward> writes:
On Sat, 15 Jul 2006 13:37:11 +1000, Jarrett Billingsley  
<kb3ctd2 yahoo.com> wrote:

 "Derek Parnell" <derek psych.ward> wrote in message
 news:op.tcpklel16b8z09 ginger.vic.bigpond.net.au...

 Excuse my ignorance, but what does an inner class provide that other
 alternatives can't?

Well, what does a nested function provide that a separate, external function doesn't? - Encapsulation - Access to outer variables - Is a Cool Thing (TM) ;) Pretty much the same thing applies to inner classes, although I'll grant you, I don't use inner classes as much as nested functions.

Ok, assuming that 'nested' and 'inner' are synonymous in this discussion, it appears that their main purpose is to provide scope limitation. That is, the functionality provided by inner classes/functions is restricted to, and there by only relevant to, the containing class/function. I use inner functions this way because I can see their utility, but can someone supply a good inner class example? As far as I can see, an instance of an inner class only makes sense in the context of its parent class and is thus reliant on the 'outer' class for relevancy. I'm having trouble visualizing where this might be a Cool Thing(TM). -- Derek Parnell Melbourne, Australia
Jul 14 2006
next sibling parent reply S. <dnewsgr mephit.kicks-ass.org> writes:
On 2006-07-14 21:10:41 -0700, "Derek Parnell" <derek psych.ward> said:

 Ok, assuming that 'nested' and 'inner' are synonymous in this 
 discussion,  it appears that their main purpose is to provide scope 
 limitation. That  is, the functionality provided by inner 
 classes/functions is restricted  to, and there by only relevant to, the 
 containing class/function.
 
 I use inner functions this way because I can see their utility, but can 
  someone supply a good inner class example? As far as I can see, an  
 instance of an inner class only makes sense in the context of its 
 parent  class and is thus reliant on the 'outer' class for relevancy. 
 I'm having  trouble visualizing where this might be a Cool Thing(TM).

I'm writing a Sudoku solver. I have a Cell class, an individual cell is only relevant in the context of the board. It makes various things a Cell might want to do easier having access to information about the board it lives on. I could pass it a board instance when I create it like I did originally, but I saw nested classes and thought it was a nifty feature. -S
Jul 15 2006
parent reply "Derek Parnell" <derek psych.ward> writes:
On Sat, 15 Jul 2006 17:50:11 +1000, S. <dnewsgr mephit.kicks-ass.org>  =

wrote:

 On 2006-07-14 21:10:41 -0700, "Derek Parnell" <derek psych.ward> said:=

 Ok, assuming that 'nested' and 'inner' are synonymous in this  =


 discussion,  it appears that their main purpose is to provide scope  =


 limitation. That  is, the functionality provided by inner  =


 classes/functions is restricted  to, and there by only relevant to, t=


 containing class/function.
  I use inner functions this way because I can see their utility, but =


 can  someone supply a good inner class example? As far as I can see, =


 an  instance of an inner class only makes sense in the context of its=


 parent  class and is thus reliant on the 'outer' class for relevancy.=


 I'm having  trouble visualizing where this might be a Cool Thing(TM).=


 I'm writing a Sudoku solver.  I have a Cell class, an individual cell =

 only relevant in the context of the board.  It makes various things a =

 Cell might want to do easier having access to information about the  =

 board it lives on.  I could pass it a board instance when I create it =

 like I did originally, but I saw nested classes and thought it was a  =

 nifty feature.

So the main reason is so Cell objects can access the Board object's = members. This can also be done just by declaring the classes in the same module, = = and thus avoid the restrictions you are tripping up on. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D module board; class Board { private Cell[9][9] arena; private int option_x; private bool Solved() { . . . } . . . } class Cell { private Board owner; this(Board b) { if (b.option_x) { . . . } owner =3D b; } this(Cell c) { owner =3D c.owner; } Cell dup() { return new Cell(this); } bool Set() { . . . return owner.Solved(); } } =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D Its just an alternative using current D syntax. No big deal ;-) -- = Derek Parnell Melbourne, Australia
Jul 15 2006
parent reply S. <user pathlink.com> writes:
On 2006-07-15 02:10:17 -0700, "Derek Parnell" <derek psych.ward> said:

 On Sat, 15 Jul 2006 17:50:11 +1000, S. <dnewsgr mephit.kicks-ass.org>
 wrote:
 
 On 2006-07-14 21:10:41 -0700, "Derek Parnell" <derek psych.ward> said:

 
 Ok, assuming that 'nested' and 'inner' are synonymous in this


 discussion,  it appears that their main purpose is to provide scope


 limitation. That  is, the functionality provided by inner


 classes/functions is restricted  to, and there by only relevant to, t


 containing class/function.
  I use inner functions this way because I can see their utility, but


 can  someone supply a good inner class example? As far as I can see,


 an  instance of an inner class only makes sense in the context of its


 parent  class and is thus reliant on the 'outer' class for relevancy.


 I'm having  trouble visualizing where this might be a Cool Thing(TM).


 
 I'm writing a Sudoku solver.  I have a Cell class, an individual cell

 only relevant in the context of the board.  It makes various things a

 Cell might want to do easier having access to information about the

 board it lives on.  I could pass it a board instance when I create it

 like I did originally, but I saw nested classes and thought it was a

 nifty feature.

So the main reason is so Cell objects can access the Board object's members. This can also be done just by declaring the classes in the same module, and thus avoid the restrictions you are tripping up on. ============= module board; class Board { private Cell[9][9] arena; private int option_x; private bool Solved() { . . . } . . . } class Cell { private Board owner; this(Board b) { if (b.option_x) { . . . } owner = b; } this(Cell c) { owner = c.owner; } Cell dup() { return new Cell(this); } bool Set() { . . . return owner.Solved(); } } =============== Its just an alternative using current D syntax. No big deal ;-) -- Derek Parnell Melbourne, Australia

That's exactly what I said: "I could pass it a board instance when I create it like I did originally, but I saw nested classes and thought it was a nifty feature." Inner classes obviate that. -S.
Jul 16 2006
parent "Derek Parnell" <derek psych.ward> writes:
On Sun, 16 Jul 2006 18:01:51 +1000, S. <user pathlink.com> wrote:


 That's exactly what I said:

 "I could pass it a board instance when I create it like I did  
 originally, but I saw nested classes and thought it was a  nifty  
 feature."

 Inner classes obviate that.

Thank you. I'm still learning every day, even though I've be doing this for IT stuff for over thirty years now ;-) -- Derek Parnell Melbourne, Australia
Jul 16 2006
prev sibling parent =?UTF-8?B?SmFyaS1NYXR0aSBNw6RrZWzDpA==?= <jmjmak utu.fi.invalid> writes:
Derek Parnell wrote:
 Ok, assuming that 'nested' and 'inner' are synonymous in this
 discussion, it appears that their main purpose is to provide scope
 limitation. That is, the functionality provided by inner
 classes/functions is restricted to, and there by only relevant to, the
 containing class/function.
 
 I use inner functions this way because I can see their utility, but can
 someone supply a good inner class example? As far as I can see, an
 instance of an inner class only makes sense in the context of its parent
 class and is thus reliant on the 'outer' class for relevancy. I'm having
 trouble visualizing where this might be a Cool Thing(TM).

Simulating multiple inheritance: class Person {} interface CompilerWriter { void writeCompiler(); } interface PersonWithIdeas { void designStuff(); } class GenericCompilerWriter : CompilerWriter { void writeCompiler() { /* some basic stuff */ } } class GenericPersonWithIdeas : PersonWithIdeas { void designStuff() { /* some basic stuff */ } } class Walter : Person, CompilerWriter, PersonWithIdeas { InnerGCW a; InnerGPWI b; this() { a = new InnerGCW(); b = new InnerGPWI(); } void writeCompiler() { a.writeCompiler(); } void designStuff() { b.designStuff(); } private class InnerGCW : GenericCompilerWriter { /* super duper implementation */ } private class InnerGPWI : GenericPersonWithIdeas { /* great ideas */ } } -- Jari-Matti
Jul 15 2006
prev sibling parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Jarrett Billingsley wrote:
 "Derek Parnell" <derek psych.ward> wrote in message 
 news:op.tcpklel16b8z09 ginger.vic.bigpond.net.au...
 
 Excuse my ignorance, but what does an inner class provide that other 
 alternatives can't?

Well, what does a nested function provide that a separate, external function doesn't? - Encapsulation - Access to outer variables

Not just _access_ to outer variables, but the concept of outer variables in the first place.
 - Is a Cool Thing (TM) ;)

An inner class is basically syntactic sugar for a static nested class that includes a reference to an object of the enclosing class as one of its members. For example, class Board { class Cell { this() { ... } } } is equivalent to class Board { static class Cell { private Board _outer; this(Board b) { _outer = b; ... } } } However, when using the static nested class approach, referring to the whole of the 'enclosing' object, and not just to a specific member thereof, becomes trivial. OTOH, to access the outer object from an inner class, you have to create a property in the outer class class Board { Board theBoard() { return this; } } and then use it within the inner class. This is a pinch of salt in the syntactic sugar that is inner classes. An 'outer' keyword would indeed be nicer. You could ask what access level outer should have. For example, should it be acceptable to do, from outside, something like this? Cell c; ... Board b = c.outer; Stewart.
Jul 16 2006
parent reply S. Chancellor <dnewsgr mephit.kicks-ass.org> writes:
On 2006-07-16 08:19:04 -0700, Stewart Gordon <smjg_1998 yahoo.com> said:

 Jarrett Billingsley wrote:
 "Derek Parnell" <derek psych.ward> wrote in message 
 news:op.tcpklel16b8z09 ginger.vic.bigpond.net.au...
 
 Excuse my ignorance, but what does an inner class provide that other 
 alternatives can't?

Well, what does a nested function provide that a separate, external function doesn't? - Encapsulation - Access to outer variables

Not just _access_ to outer variables, but the concept of outer variables in the first place.
 - Is a Cool Thing (TM) ;)

An inner class is basically syntactic sugar for a static nested class that includes a reference to an object of the enclosing class as one of its members. For example, class Board { class Cell { this() { ... } } } is equivalent to class Board { static class Cell { private Board _outer; this(Board b) { _outer = b; ... } } } However, when using the static nested class approach, referring to the whole of the 'enclosing' object, and not just to a specific member thereof, becomes trivial. OTOH, to access the outer object from an inner class, you have to create a property in the outer class class Board { Board theBoard() { return this; } } and then use it within the inner class. This is a pinch of salt in the syntactic sugar that is inner classes. An 'outer' keyword would indeed be nicer. You could ask what access level outer should have. For example, should it be acceptable to do, from outside, something like this? Cell c; ... Board b = c.outer; Stewart.

Exactly. Interestingly though I tried this: class Board { Board outer; this() { outer = this; } class Cell { Cell dup() { return new outer.Cell; } } and I get syntax errors. This new expression stuff seems broken.
Jul 16 2006
parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
S. Chancellor wrote:
 Exactly.  Interestingly though I tried this:
 
 class Board {
     Board outer;
     this() { outer = this; }
     class Cell {
         Cell dup() {
             return new outer.Cell;
         }
     }
 
 and I get syntax errors.   This new expression stuff seems broken.

First thing you'll want to do is close all your braces. You missed one :). The 'new' syntax is a bit weird for inner classes I think. This should work: class Board { Board outer; this() { outer = this; } class Cell { Cell dup() { return outer.new Cell; } } } I agree that 'new outer.Cell' is a more intuitive syntax for this, but that's just not the way it works... This is also the syntax for 'new'ing an inner class in Java, IIRC. I remember tripping over the syntax a couple of times when I was using Java. (I haven't needed inner classes in D yet[1]) See also http://www.digitalmars.com/d/class.html (almost at the very end, just above the heading "Anonymous Nested Classes")
Jul 16 2006
parent reply S. <S._member pathlink.com> writes:
In article <e9e8h8$1asn$1 digitaldaemon.com>, Frits van Bommel says...
S. Chancellor wrote:
 Exactly.  Interestingly though I tried this:
 
 class Board {
     Board outer;
     this() { outer = this; }
     class Cell {
         Cell dup() {
             return new outer.Cell;
         }
     }
 
 and I get syntax errors.   This new expression stuff seems broken.

First thing you'll want to do is close all your braces. You missed one :). The 'new' syntax is a bit weird for inner classes I think. This should work: class Board { Board outer; this() { outer = this; } class Cell { Cell dup() { return outer.new Cell; } } } I agree that 'new outer.Cell' is a more intuitive syntax for this, but that's just not the way it works... This is also the syntax for 'new'ing an inner class in Java, IIRC. I remember tripping over the syntax a couple of times when I was using Java. (I haven't needed inner classes in D yet[1]) See also http://www.digitalmars.com/d/class.html (almost at the very end, just above the heading "Anonymous Nested Classes")

I made some typo's -- that is not the verbatim code I was tring to compile. I had outer.new Cell and all my braces closed. Did you try to compile yours?
Jul 17 2006
parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
S. wrote:
 In article <e9e8h8$1asn$1 digitaldaemon.com>, Frits van Bommel says...
 S. Chancellor wrote:
 Exactly.  Interestingly though I tried this:

 class Board {
     Board outer;
     this() { outer = this; }
     class Cell {
         Cell dup() {
             return new outer.Cell;
         }
     }

 and I get syntax errors.   This new expression stuff seems broken.

The 'new' syntax is a bit weird for inner classes I think. This should work: class Board { Board outer; this() { outer = this; } class Cell { Cell dup() { return outer.new Cell; } } } I agree that 'new outer.Cell' is a more intuitive syntax for this, but that's just not the way it works... This is also the syntax for 'new'ing an inner class in Java, IIRC. I remember tripping over the syntax a couple of times when I was using Java. (I haven't needed inner classes in D yet[1]) See also http://www.digitalmars.com/d/class.html (almost at the very end, just above the heading "Anonymous Nested Classes")

I made some typo's -- that is not the verbatim code I was tring to compile. I

Copy-paste is very handy when complaining about compile errors ;). You might want to copy-paste the errors themselves too.
 had outer.new Cell and all my braces closed.  Did you try to compile yours?

Yes I did. And I just did it again. Compiles just fine: D:\Temp>cat test.d class Board { Board outer; this() { outer = this; } class Cell { Cell dup() { return outer.new Cell; } } } D:\Temp>dmd -c test.d D:\Temp> That's DMD v0.161 though. v0.162 has an unrelated bug causing it to segfault when compiling some of my code :(.
Jul 17 2006
parent S. <S._member pathlink.com> writes:
In article <e9gck1$grg$1 digitaldaemon.com>, Frits van Bommel says...
S. wrote:
 In article <e9e8h8$1asn$1 digitaldaemon.com>, Frits van Bommel says...
 S. Chancellor wrote:
 Exactly.  Interestingly though I tried this:

 class Board {
     Board outer;
     this() { outer = this; }
     class Cell {
         Cell dup() {
             return new outer.Cell;
         }
     }

 and I get syntax errors.   This new expression stuff seems broken.

The 'new' syntax is a bit weird for inner classes I think. This should work: class Board { Board outer; this() { outer = this; } class Cell { Cell dup() { return outer.new Cell; } } } I agree that 'new outer.Cell' is a more intuitive syntax for this, but that's just not the way it works... This is also the syntax for 'new'ing an inner class in Java, IIRC. I remember tripping over the syntax a couple of times when I was using Java. (I haven't needed inner classes in D yet[1]) See also http://www.digitalmars.com/d/class.html (almost at the very end, just above the heading "Anonymous Nested Classes")

I made some typo's -- that is not the verbatim code I was tring to compile. I

Copy-paste is very handy when complaining about compile errors ;). You might want to copy-paste the errors themselves too.
 had outer.new Cell and all my braces closed.  Did you try to compile yours?

Yes I did. And I just did it again. Compiles just fine: D:\Temp>cat test.d class Board { Board outer; this() { outer = this; } class Cell { Cell dup() { return outer.new Cell; } } } D:\Temp>dmd -c test.d D:\Temp> That's DMD v0.161 though. v0.162 has an unrelated bug causing it to segfault when compiling some of my code :(.

The problem I discovered was in the error message and dlint. Dlint was highlighting that line and the compiler was generating an error about an indentifier without quoting it. It just so happened my variable name fit in strangely with the message -- leaving me highly confused. Everything works now. -S.
Jul 17 2006