www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Proposal keyword 'outer'

reply Frank Benoit <keinfarbton nospam.xyz> writes:
For inner classes and mixins, it would be good to have a reference to
the next outer scope.

class C{
 int i; // 1
 class C1{
  int i; // 2
  void func( int a ){
   i = a; // assign to 2
   outer.i = a; // assign to 1
  }
 }
}

In case of a mixin, outer is the scope of the instantiation.

outer can be chained like outer.outer.func() to go out in scope two levels.
Jun 20 2006
next sibling parent Tom S <h3r3tic remove.mat.uni.torun.pl> writes:
Frank Benoit wrote:
 For inner classes and mixins, it would be good to have a reference to
 the next outer scope.
 
 class C{
  int i; // 1
  class C1{
   int i; // 2
   void func( int a ){
    i = a; // assign to 2
    outer.i = a; // assign to 1
   }
  }
 }
 
 In case of a mixin, outer is the scope of the instantiation.
 
 outer can be chained like outer.outer.func() to go out in scope two levels.

I second that. Especially for mixins. In their current form, mixins are very error prone and using without caution begs for hard to spot errors. One of the points of using mixins is for them to use the scope of their instantiation without any problems. But this is a huge problem itself. Let's say you write a module: module a; int someVar; template MyMix() { void foo() { someVar = 1; } } if you then use that module like this: module b; import a; mixin MyMix; ... foo(); then everything is fine and the mixin uses the 'someVar' from 'a'. But if you use it like that: module c; private import a; int someVar; mixin MyMix; ... foo(); then you may have some hard time figuring out what's going on. One might claim that in this case the programmer's assumptions are invalid, but then the current visibility rules in mixins are different from any other construct in D and thus yield themselves to mistakes. Assumptions are one thing and typos are another. The same situation might happen because of a typo and would probably be harder to track down than any other typo. Another problem is that sometimes mixins should be able to use symbols from the modules they were defined in. The 'outer' keyword suggestion would solve these problems in a consistent manner. Mixins would by default see the scope of their declaration and the 'outer' keyword would allow them to access the instantiation scope. No hidden problems, code 'injection' or inconsistencies. ++votes; -- Tomasz Stachowiak /+ a.k.a. h3r3tic +/
Jun 20 2006
prev sibling next sibling parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Frank Benoit" <keinfarbton nospam.xyz> wrote in message 
news:e78h69$104t$1 digitaldaemon.com...

 For inner classes and mixins, it would be good to have a reference to
 the next outer scope.

Agree. It's dumb to have the context pointer there, but inaccessible.
Jun 20 2006
parent Rémy Mouëza <Rémy_member pathlink.com> writes:
In article <e793to$28or$1 digitaldaemon.com>, Jarrett Billingsley says...
"Frank Benoit" <keinfarbton nospam.xyz> wrote in message 
news:e78h69$104t$1 digitaldaemon.com...

 For inner classes and mixins, it would be good to have a reference to
 the next outer scope.

Agree. It's dumb to have the context pointer there, but inaccessible.

I've played with mixin inheritance : # template Mix ( T ) # { # class Mix : T # { # void method ( something ) # { # super.method ( super.stuff, something ); # ... # } # } # } Then one can add behaviours and attributes to an existing class: # auto mixedIn = new Mix !( MyPoorLittleClass ) ; and the mixin code have access to the enclosing context through the super pointer. It may help waiting the outer keyword.
Jun 20 2006
prev sibling parent reply Bruno Medeiros <brunodomedeirosATgmail SPAM.com> writes:
Frank Benoit wrote:
 For inner classes and mixins, it would be good to have a reference to
 the next outer scope.
 
 class C{
  int i; // 1
  class C1{
   int i; // 2
   void func( int a ){
    i = a; // assign to 2
    outer.i = a; // assign to 1
   }
  }
 }
 
 In case of a mixin, outer is the scope of the instantiation.
 
 outer can be chained like outer.outer.func() to go out in scope two levels.

Seems an ok proposal for outer classes. But as for mixins that doesn't make sense, the scope they access is already the scope of the instantiation. -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Jun 23 2006
parent reply Tom S <h3r3tic remove.mat.uni.torun.pl> writes:
Bruno Medeiros wrote:
 Seems an ok proposal for outer classes.
 But as for mixins that doesn't make sense, the scope they access is 
 already the scope of the instantiation.

That's the point. The rules for mixins must change as they are inconsistent and error prone at the moment. IMO they should only be granted access to the outer scope thru the 'outer' keyword and by default only see the scope of their declaration. -- Tomasz Stachowiak /+ a.k.a. h3r3tic +/
Jun 23 2006
parent reply Bruno Medeiros <brunodomedeirosATgmail SPAM.com> writes:
Tom S wrote:
 Bruno Medeiros wrote:
 Seems an ok proposal for outer classes.
 But as for mixins that doesn't make sense, the scope they access is 
 already the scope of the instantiation.

That's the point. The rules for mixins must change as they are inconsistent and error prone at the moment. IMO they should only be granted access to the outer scope thru the 'outer' keyword and by default only see the scope of their declaration.

Ok, but then that's a whole other issue altogether. -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Jun 25 2006
parent reply Tom S <h3r3tic remove.mat.uni.torun.pl> writes:
Bruno Medeiros wrote:
 Tom S wrote:
 Bruno Medeiros wrote:
 Seems an ok proposal for outer classes.
 But as for mixins that doesn't make sense, the scope they access is 
 already the scope of the instantiation.

That's the point. The rules for mixins must change as they are inconsistent and error prone at the moment. IMO they should only be granted access to the outer scope thru the 'outer' keyword and by default only see the scope of their declaration.

Ok, but then that's a whole other issue altogether.

Uhmm... how ? You said it didn't make sense for mixins and I claim that it does and that they will benefit from the 'outer' keyword. Actually, it's more important for them than for inner classes, as the current rules for mixins are way borked IMO... Seems to me like D needs a major rehash of its visibility rules... -- Tomasz Stachowiak /+ a.k.a. h3r3tic +/
Jun 25 2006
next sibling parent reply Don Clugston <dac nospam.com.au> writes:
Tom S wrote:
 Bruno Medeiros wrote:
 Tom S wrote:
 Bruno Medeiros wrote:
 Seems an ok proposal for outer classes.
 But as for mixins that doesn't make sense, the scope they access is 
 already the scope of the instantiation.

That's the point. The rules for mixins must change as they are inconsistent and error prone at the moment. IMO they should only be granted access to the outer scope thru the 'outer' keyword and by default only see the scope of their declaration.

Ok, but then that's a whole other issue altogether.

Uhmm... how ? You said it didn't make sense for mixins and I claim that it does and that they will benefit from the 'outer' keyword. Actually, it's more important for them than for inner classes, as the current rules for mixins are way borked IMO...

It's really important that mixins be able to access outer variables without knowing how deep they are. I think this is quite different from the situation for inner classes. ie, in a mixin, if you had to write outer.outer.outer.x mixins would lose most of their power. I'd be in favour of syntax which said: (a) this template is intended for use as a mixin; and (b) I'm importing the next symbol from _somewhere_ outside the mixin.
 Seems to me like D needs a major rehash of its visibility rules...

I don't think anyone would disagree with that. Seems to have become the #1 D issue right now.
Jun 25 2006
parent reply Tom S <h3r3tic remove.mat.uni.torun.pl> writes:
Don Clugston wrote:
 It's really important that mixins be able to access outer variables 
 without knowing how deep they are.  I think this is quite different from 
 the situation for inner classes.
 
 ie, in a mixin, if you had to write
 
 outer.outer.outer.x
 
 mixins would lose most of their power.

Wouldn't this be a problem only in case of instantiating mixins recursively inside other mixins ? I'd then use an alias in the recursive mixin template that brings the required symbol to the mixin's scope, like 'private alias outer.foo foo'. Then the nested mixin would only have to use 'outer.foo' to get the indefinitely deep symbol. That combined with my previous proposal: digitalmars.D/39135 would make it at least workable...
 I'd be in favour of syntax which said:
 (a) this template is intended for use as a mixin; and

Agreed. 'mixin template foo() {}' or just 'mixin foo() {}' would be much more explicit...
 (b) I'm importing the next symbol from _somewhere_ outside the mixin.

This would also be an option for the 'outer' keyword. 'outer.foo' could just mean that. Take 'foo' from _somewhere_ outside the mixin. Thanks for answering... I thought I was the only one concerned about mixin visibility rules :/ -- Tomasz Stachowiak /+ a.k.a. h3r3tic +/
Jun 26 2006
parent reply "Rioshin an'Harthen" <rharth75 hotmail.com> writes:
"Tom S" <h3r3tic remove.mat.uni.torun.pl> wrote in message 
news:e7o633$1ms9$1 digitaldaemon.com...
 Don Clugston wrote:
 It's really important that mixins be able to access outer variables 
 without knowing how deep they are.  I think this is quite different from 
 the situation for inner classes.

 ie, in a mixin, if you had to write

 outer.outer.outer.x

 mixins would lose most of their power.

Wouldn't this be a problem only in case of instantiating mixins recursively inside other mixins ? I'd then use an alias in the recursive mixin template that brings the required symbol to the mixin's scope, like 'private alias outer.foo foo'. Then the nested mixin would only have to use 'outer.foo' to get the indefinitely deep symbol.

What about instantiating a mixin from an inner class? Wouldn't the first outer then access only those items in the inner class, and a second one be needed to get to the next class upwards? Now, you would need to alias those symbols in the inner class for the mixin.
 That combined with my previous proposal: 
 digitalmars.D/39135

 would make it at least workable...


 I'd be in favour of syntax which said:
 (a) this template is intended for use as a mixin; and

Agreed. 'mixin template foo() {}' or just 'mixin foo() {}' would be much more explicit...

Of these, I prefer the syntax of mixin template foo() {}. That states more clearly what is intended - that the template following is intended to be used as a mixin. Should it also be illegal to use a mixin template as anything other than a mixin? Tentatively, I'd say yes.
 (b) I'm importing the next symbol from _somewhere_ outside the mixin.

This would also be an option for the 'outer' keyword. 'outer.foo' could just mean that. Take 'foo' from _somewhere_ outside the mixin.

I would actually go for this for both mixins and inner classes. I think it would be preferable to be consistent with the use of the keyword; i.e. if we make mixin template Gnusto() { outer.b = outer.a; } to mean any variable in the scope, following a chain of scopes through outer classes, from where Foo is instantiated, then so should class Foo { public int a; class Bar { public int b; class Baz { void blorb() { outer.b = outer.a; } void gnusto() { mixin Gnusto!(); } } } } work, as well. Basically, the code brought in by the mixin in gnusto, matches exactly the same code in blorb. Both evaluate to outer.b = outer.a, and if one method is allowed, while the other would require outer.b = outer.outer.a, then I for one would see it as broken.
Jun 26 2006
parent Tom S <h3r3tic remove.mat.uni.torun.pl> writes:
Rioshin an'Harthen wrote:
 What about instantiating a mixin from an inner class? Wouldn't the first 
 outer then access only those items in the inner class, and a second one be 
 needed to get to the next class upwards?
 
 Now, you would need to alias those symbols in the inner class for the mixin.

Yup, or use a different mixin. I don't think it's a big deal. Mixins can hide lots of code, sometimes too much -> they can be hard to maintain. Making their use a bit more explicit shouldn't hurt in the long run.
 Should it also be illegal to use a mixin template as anything other than a 
 mixin? Tentatively, I'd say yes.

Agreed.
 I would actually go for this for both mixins and inner classes. I think it 
 would be preferable to be consistent with the use of the keyword;

I don't use inner classes so I can't tell how the people that do would feel, but it doesn't seem very bad. -- Tomasz Stachowiak /+ a.k.a. h3r3tic +/
Jun 26 2006
prev sibling parent Bruno Medeiros <brunodomedeirosATgmail SPAM.com> writes:
Tom S wrote:
 Bruno Medeiros wrote:
 Tom S wrote:
 Bruno Medeiros wrote:
 Seems an ok proposal for outer classes.
 But as for mixins that doesn't make sense, the scope they access is 
 already the scope of the instantiation.

That's the point. The rules for mixins must change as they are inconsistent and error prone at the moment. IMO they should only be granted access to the outer scope thru the 'outer' keyword and by default only see the scope of their declaration.

Ok, but then that's a whole other issue altogether.

Uhmm... how ? You said it didn't make sense for mixins and I claim that it does and that they will benefit from the 'outer' keyword. Actually, it's more important for them than for inner classes, as the current rules for mixins are way borked IMO...

'outer' for mixins only makes sense if you change the instantiation rules for mixins. What I was saying is that adding 'outer' for inner classes is a whole different issue than changing the instantiation rules for mixins, despite seeming related because they would both use the keyword 'outer'. (and as such the two issues shouldn't bundled as one ;) ) -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Jun 26 2006