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 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.

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

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

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. :-)

(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.)

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

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).

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).

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

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.

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.

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 :)
-Steve

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