digitalmars.D - Inner classes - More expressiveness needed
- Janice Caron (23/23) Oct 25 2007 I can't call this a bug, because I think it's behaving as documented.
- Jarrett Billingsley (11/34) Oct 25 2007 I have no idea how that'd be implemented. The thing is that the 'outer'...
- Gregor Richards (11/11) Oct 25 2007 I hate when people say that "static" is overused, when they really just
- Matti Niemenmaa (12/25) Oct 25 2007 Even if you count "static assert" as a conditional, there's still "stati...
- Henning Hasemann (18/27) Oct 25 2007 'import' has 2: 'import foo', 'import("foo")'
- Matti Niemenmaa (8/20) Oct 25 2007 Gregor grouped static's 7 meanings into 2. I did the same with 'import' ...
- Derek Parnell (11/26) Oct 25 2007 How does the module constructor fit into this classification?
- Steven Schveighoffer (9/31) Oct 25 2007 And what would you have the outer member point to? :) It needs to point...
- Janice Caron (43/49) Oct 25 2007 Hmm... How to explain...?
- Steven Schveighoffer (5/54) Oct 25 2007 Yeah, I see your point. I don't think there's a way to name the functio...
- Nathan Reed (13/43) Oct 25 2007 Isn't what you want just a member function of Outer?
I can't call this a bug, because I think it's behaving as documented. Nonetheless, it seems to be that D could be more expressive. The following won't compile: class Outer { int n; class Inner { static int f() { return n; } } } The error is: Error: need 'this' to access member n The problem is that the word "static" is horribly overused, and doubles up to mean BOTH "the function does not have a this pointer" AND "this function does not have an outer pointer". There seems no way to express "please can my function have an outer pointer but not a this pointer" (which is what I was trying to achieve). There also seems no way to express "please can my function have a this pointer but not an outer pointer". (I wasn't trying to achieve that, but it could conceivably be useful). I wonder if we might find some way of expressing those ideas?
Oct 25 2007
"Janice Caron" <caron800 googlemail.com> wrote in message news:mailman.508.1193317715.16939.digitalmars-d puremagic.com...I can't call this a bug, because I think it's behaving as documented. Nonetheless, it seems to be that D could be more expressive. The following won't compile: class Outer { int n; class Inner { static int f() { return n; } } } The error is: Error: need 'this' to access member n The problem is that the word "static" is horribly overused, and doubles up to mean BOTH "the function does not have a this pointer" AND "this function does not have an outer pointer". There seems no way to express "please can my function have an outer pointer but not a this pointer" (which is what I was trying to achieve). There also seems no way to express "please can my function have a this pointer but not an outer pointer". (I wasn't trying to achieve that, but it could conceivably be useful). I wonder if we might find some way of expressing those ideas?I have no idea how that'd be implemented. The thing is that the 'outer' is not contained somewhere special; it's just a hidden member of every instance of the inner class. When you access outer members, you're really doing this.outer.member. For a static inner function, however, there's no way to associate an "instance of the function" (which doesn't really mean much) with an instance of Outer. Furthermore there are (please don't hit me) static inner classes, which do not have an outer pointer. Again, the outer pointer is per-instance, so this just involves not putting an outer pointer in the instance.
Oct 25 2007
I hate when people say that "static" is overused, when they really just don't know what static means. There are only two meanings for "static" in D: * Static conditionals. * Static declarations. For static declarations, the meaning of static is 100% consistent. It means that the given declaration, though accessed by its semantic scope, exists in the global context. Implementation-wise, this means that it has no context pointer whatsoever. This is far more consistent than C, C++, Java, ... - Gregor Richards
Oct 25 2007
Gregor Richards wrote:I hate when people say that "static" is overused, when they really just don't know what static means. There are only two meanings for "static" in D: * Static conditionals. * Static declarations. For static declarations, the meaning of static is 100% consistent. It means that the given declaration, though accessed by its semantic scope, exists in the global context. Implementation-wise, this means that it has no context pointer whatsoever. This is far more consistent than C, C++, Java, ...Even if you count "static assert" as a conditional, there's still "static import", which is already three completely distinct uses for one keyword. The only other keyword with that many is "in". (One of which you might not even count, as it's obvious to anybody without programming experience what "a in b" means. With "static", none of the meanings are as obvious.) As far as I can come up with, "out", "scope", and "void" have two distinct meanings, and the rest have one. So, despite knowing what "static" means, I'd say it's the most used keyword in the language, and overused. -- E-mail address: matti.niemenmaa+news, domain is iki (DOT) fi
Oct 25 2007
Even if you count "static assert" as a conditional, there's still "static import", which is already three completely distinct uses for one keyword. The only other keyword with that many is "in". (One of which you might not even count, as it's obvious to anybody without programming experience what "a in b" means. With "static", none of the meanings are as obvious.) As far as I can come up with, "out", "scope", and "void" have two distinct meanings, and the rest have one.'import' has 2: 'import foo', 'import("foo")' 'mixin' has at least 2: 'mixin Foo!()', 'mixin("foo")' 'this' has at least 2: 'this() { }', 'this.foo' 'alias' has at least 2: 'alias myint int;', 'tempalte Templ(alias T){}' I'd guess one could find more examples (const in D2?). I dislike this too. I dont think its such a big problem to have more keywords, especially when they denote different features. But it seems to me Walter & co are more concerned about polluting the code namespace then by this problem. (Which has it good sides too when it comes to backwards compatibility, but I feel it should be more important to choose expressive keywords then retaining backwards compatibility especially in the 2.x branch I think it would be a good idea to reconsider keyword choices as backwards compatibility is not an issue there.) Henning -- GPG Public Key: http://gpg-keyserver.de/pks/lookup?op=get&search=0xDDD6D36D41911851
Oct 25 2007
Henning Hasemann wrote:Gregor grouped static's 7 meanings into 2. I did the same with 'import' and 'mixin' in the above. I'd say you're right about 'this' at least, and I never understood template alias parameters so you're probably right about that one, too. :-)As far as I can come up with, "out", "scope", and "void" have two distinct meanings, and the rest have one.'import' has 2: 'import foo', 'import("foo")' 'mixin' has at least 2: 'mixin Foo!()', 'mixin("foo")' 'this' has at least 2: 'this() { }', 'this.foo' 'alias' has at least 2: 'alias myint int;', 'tempalte Templ(alias T){}'(Which has it good sides too when it comes to backwards compatibility, but I feel it should be more important to choose expressive keywords then retaining backwards compatibility especially in the 2.x branch I think it would be a good idea to reconsider keyword choices as backwards compatibility is not an issue there.)Agreed. -- E-mail address: matti.niemenmaa+news, domain is iki (DOT) fi
Oct 25 2007
On Thu, 25 Oct 2007 08:09:34 -0700, Gregor Richards wrote:I hate when people say that "static" is overused, when they really just don't know what static means. There are only two meanings for "static" in D: * Static conditionals. * Static declarations. For static declarations, the meaning of static is 100% consistent. It means that the given declaration, though accessed by its semantic scope, exists in the global context. Implementation-wise, this means that it has no context pointer whatsoever. This is far more consistent than C, C++, Java, ... - Gregor RichardsHow does the module constructor fit into this classification? module xyz; static this() { . . . } -- Derek Parnell Melbourne, Australia skype: derek.j.parnell
Oct 25 2007
"Janice Caron" wroteI can't call this a bug, because I think it's behaving as documented. Nonetheless, it seems to be that D could be more expressive. The following won't compile: class Outer { int n; class Inner { static int f() { return n; } } } The error is: Error: need 'this' to access member n The problem is that the word "static" is horribly overused, and doubles up to mean BOTH "the function does not have a this pointer" AND "this function does not have an outer pointer". There seems no way to express "please can my function have an outer pointer but not a this pointer" (which is what I was trying to achieve).And what would you have the outer member point to? :) It needs to point to an instance of the outer class, and if you have a static function, there is no instance of an inner or outer class. If you need a function that requires an instance of the outer class, but not an instance of the inner class, the function belongs in the outer class. I think that is what you wanted?There also seems no way to express "please can my function have a this pointer but not an outer pointer". (I wasn't trying to achieve that, but it could conceivably be useful).This is done by creating another class in the same module. -Steve
Oct 25 2007
On 10/25/07, Steven Schveighoffer <schveiguy yahoo.com> wrote:And what would you have the outer member point to? :) It needs to point to an instance of the outer class, and if you have a static function, there is no instance of an inner or outer class. If you need a function that requires an instance of the outer class, but not an instance of the inner class, the function belongs in the outer class. I think that is what you wanted?Hmm... How to explain...? OK, to start with, I had a class which looked something like this: class B { int n; private this(int n) { this.n = n; } static B opCall(int n) { return new B(n); } int f() { return 0; } } B B_Factory(int n) { return new B(n); } // In another file auto b = B(42); int n = b.f; This all worked very nicely. But then I decided to make B an inner class, so naturally I tried just wrapping it in class A {}, to give class A { int m; class B { int n; private this(int n) { this.n = n; } static B opCall(int n) { return new B(n); } int f() { return m; } } B B_Factory(int n) { return new B(n); } } // In another file auto a = new A; auto b = a.B(42); int n = b.f; and this is the point at which it stopped compiling. I guess maybe it was a dumb thing to do, using static opCall and making the constructor private. The thing is, while the static opCall does not compile, the standalone function B_factory() is perfectly OK and compiles just fine. That's because B_Factory is considered to be a member function of A, wheras A.B.opCall() isn't. So, when you said "If you need a function that requires an instance of the outer class, but not an instance of the inner class, the function belongs in the outer class", you were spot on! I can't argue with that. It just came as a bit of a surprise that wrapping a bunch of classes inside class A() caused some static functions to stop working.
Oct 25 2007
"Janice Caron" wroteOn 10/25/07, Steven Schveighoffer <schveiguy yahoo.com> wrote:Yeah, I see your point. I don't think there's a way to name the function a.B() without having a static opCall, which isn't what you want. So I guess B_Factory will have to do :) -SteveAnd what would you have the outer member point to? :) It needs to point to an instance of the outer class, and if you have a static function, there is no instance of an inner or outer class. If you need a function that requires an instance of the outer class, but not an instance of the inner class, the function belongs in the outer class. I think that is what you wanted?Hmm... How to explain...? OK, to start with, I had a class which looked something like this: class B { int n; private this(int n) { this.n = n; } static B opCall(int n) { return new B(n); } int f() { return 0; } } B B_Factory(int n) { return new B(n); } // In another file auto b = B(42); int n = b.f; This all worked very nicely. But then I decided to make B an inner class, so naturally I tried just wrapping it in class A {}, to give class A { int m; class B { int n; private this(int n) { this.n = n; } static B opCall(int n) { return new B(n); } int f() { return m; } } B B_Factory(int n) { return new B(n); } } // In another file auto a = new A; auto b = a.B(42); int n = b.f; and this is the point at which it stopped compiling. I guess maybe it was a dumb thing to do, using static opCall and making the constructor private. The thing is, while the static opCall does not compile, the standalone function B_factory() is perfectly OK and compiles just fine. That's because B_Factory is considered to be a member function of A, wheras A.B.opCall() isn't.
Oct 25 2007
Janice Caron wrote:I can't call this a bug, because I think it's behaving as documented. Nonetheless, it seems to be that D could be more expressive. The following won't compile: class Outer { int n; class Inner { static int f() { return n; } } } The error is: Error: need 'this' to access member n The problem is that the word "static" is horribly overused, and doubles up to mean BOTH "the function does not have a this pointer" AND "this function does not have an outer pointer". There seems no way to express "please can my function have an outer pointer but not a this pointer" (which is what I was trying to achieve). There also seems no way to express "please can my function have a this pointer but not an outer pointer". (I wasn't trying to achieve that, but it could conceivably be useful). I wonder if we might find some way of expressing those ideas?Isn't what you want just a member function of Outer? If you need to get at it through an object of type Inner, you could simply use a forwarding function, e.g.: class Outer { int n; int f() { return n; } class Inner { int f() { return outer.f(); } } } Thanks, Nathan Reed
Oct 25 2007