May 27, 2004
Hauke Duden wrote:

> Walter wrote:
> 
>> "Kris" <someidiot@earthlink.dot.dot.dot.net> wrote in message
>> news:c92pp0$2qsf$1@digitaldaemon.com...
>>
>>> Is it not possible to bind explicit use of "this.method()" to the
>>> enclosing  class, rather then any derivative overload?
>>
>> On second thought, you're right. I'll make the change.
> 
> I think that'd be a mistake. There is a programming style (often used by JAVA programmers) that does not use any prefixes for member variables. Instead, if the name of a member variable should conflict with a local variable, these people use this.varname to access the member.
> 
> If you need to call a method in a fully qualified way, why not use the normal way? I.e. CLASSNAME.method() ?

I second this, since you could do typeof(this).method();

 -- andy
May 27, 2004
Walter wrote:
> "Hauke Duden" <H.NS.Duden@gmx.net> wrote in message
> news:c939g8$h6c$1@digitaldaemon.com...
> 
>>I think that'd be a mistake. There is a programming style (often used by
>>JAVA programmers) that does not use any prefixes for member variables.
>>Instead, if the name of a member variable should conflict with a local
>>variable, these people use this.varname to access the member.
> 
> 
> I think the this.member() being direct, rather than virtual, call is what
> Java does, and I haven't seen it listed as a mistake in Java's design.

If that is true then it proves my point. I have been programming on and off in JAVA for the last half a dozen years and I didn't know that. I don't use the "this.XXX" style, so that's why I never tripped about this, but if I had read "this.method()" I would sure as hell have assumed it to be the same as

CLASSNAME ref=this;
ref.method();

It is hugely inconsistent if it isn't!


>>The same should be true for methods, especially since D supports local
>>methods. It is also the only consistent way. "this" is a reference to
>>the current object, so <reference>.method() should behave the same, no
>>matter if you use a reference variable or "this". Special handling of
>>"this" will just make everything more complicated and harder to
> 
> understand.
> 
> It already does this with super.member, this.member just makes it more
> consistent (depending on how you look at it).

But super is not a reference - if it was then it would be the same as "this", wouldn't it? It is an alias for the base class name.

>>If you need to call a method in a fully qualified way, why not use the
>>normal way? I.e. CLASSNAME.method() ?
> 
> 
> That usually caused problems for me when cutting & pasting code :-(

Urrrgh. You publicly admit to frequently cutting & pasting? Don't you know that it is the greatest sin in programming? ;)

But seriously, it doesn't have to be the class name. typeof(this), as someone else mentioned, could be an alternative way to do this (using the classname should still be possible, though). As long as "this" stays a normal reference.

Besides, when you only have super and this for qualification then you still can't access overloaded methods that are lower in the hierarchy.


Hauke


May 27, 2004
I made a mistake. Java does not allow this.method() to access overridden
methods. So I'll back out that change - we'll go with the
typeof(this).method().


May 27, 2004
In article <c94duq$25kf$1@digitaldaemon.com>, Walter says...
>
>I made a mistake. Java does not allow this.method() to access overridden
>methods. So I'll back out that change - we'll go with the
>typeof(this).method().
>
>

in java you can do:
ClassName.this.method();

typeof(this).method(); looks like a static method to me:
not really what we a talking about.

Ant


May 27, 2004
"Walter"  wrote
> I made a mistake. Java does not allow this.method() to access overridden methods. So I'll back out that change - we'll go with the
typeof(this).method().

Well, perhaps I initiated that mistake. In fact there seems to be a number of mistakes here.

1) the initial request was to support a means of constraining method invocations to the enclosing class in a manner similar to how the "super." prefix operates. The implied suggestion was to use a "this." prefix, which would constrain method virtualization to within said enclosing class.

2) An alternative to the use of  "this." via the syntax "typeof(this)." has
been suggested to achieve the same thing.

3) Both these ideas are were (I think) based on the notion that method and field access should be more symmetrical. That is, there ought to be a way to explicitly say "I want that method from that class", just as you can do with exposed class fields. This assumes said class is within the (subclass) hierarchy of the requestor.

4) I had noted a recollection that Java supported #1 via the syntax "this.", and possibly through the "Class.this." incantation.

5) Walter notes (above) that "Java does not allow this.method() to access
overridden methods".

~~~~~~~~~~~~~~~~~~~~~~~

First, let's examine what Java does:

Applying "this." or "Class.this." prefixes to Java methods does NOT constrain the invocation to the targeted class instance. Nor does the casting of an instance to a target class. While field access DOES operate in the manner expected, overridden methods are invoked the same way as without the prefix. That is, the only way that Java constrains method overrides is via the "super." prefix. This invalidates #3,  #4, and #5 above.

Now, how about that alternative:

The alternative syntax "typeof(this)." would appear to conflict with the invocation of a static D method. That is, it appears to be the equivalent of a function rather than a delegate invocation. The initial request was in the context of a valid this-pointer, within an instantiated class instance. This infers a delegate approach.

What to do?

The initial issue still stands: there is real potential for nasty bugs, though manifestation is likely to be somewhat outside of mainstream development. I'd really like to see a language-level solution for it, but the "typeof(this)." approach does not appear to be adequate ...

- Kris


May 27, 2004
"Kris" <someidiot@earthlink.dot.dot.dot.net> wrote in message news:c957jp$15fn$1@digitaldaemon.com...
> "Walter"  wrote
> > I made a mistake. Java does not allow this.method() to access overridden methods. So I'll back out that change - we'll go with the
typeof(this).method().
> 5) Walter notes (above) that "Java does not allow this.method() to access
> overridden methods".

The relevant wording from the Java spec 8.4.6.2: "A hidden method can be accessed by using a qualified name or by using a method invocation expression (15.11) that contains the keyword super or a cast to a superclass type."

> First, let's examine what Java does:
>
> Applying "this." or "Class.this." prefixes to Java methods does NOT constrain the invocation to the targeted class instance.

Correct,  although I don't believe "Class.this" is valid java syntax.

> Nor does the
> casting of an instance to a target class.

This is not correct.

> While field access DOES operate in
> the manner expected, overridden methods are invoked the same way as
without
> the prefix. That is, the only way that Java constrains method overrides is via the "super." prefix.

Not correct according to the Java spec.

> This invalidates #3,  #4, and #5 above.
>
> Now, how about that alternative:
>
> The alternative syntax "typeof(this)." would appear to conflict with the invocation of a static D method.

No, it doesn't. typeof(this).method() is semantically the same as
ClassName.method(), which gets an implicit 'this' if in a non-static member
function.

> That is, it appears to be the equivalent of
> a function rather than a delegate invocation. The initial request was in
the
> context of a valid this-pointer, within an instantiated class instance.
This
> infers a delegate approach.
>
> What to do?
>
> The initial issue still stands: there is real potential for nasty bugs, though manifestation is likely to be somewhat outside of mainstream development. I'd really like to see a language-level solution for it, but the "typeof(this)." approach does not appear to be adequate ...

I think the typeof(this) solves the problem.


May 27, 2004
Kris wrote:
> The alternative syntax "typeof(this)." would appear to conflict with the
> invocation of a static D method. That is, it appears to be the equivalent of
> a function rather than a delegate invocation. The initial request was in the
> context of a valid this-pointer, within an instantiated class instance. This
> infers a delegate approach.

It can't be ambigious because the exact method being called can always be deduced from the argument types.

class A {
   void foo() { A.foo(9); } // unambigious.  A.foo(int) is not static, so 'this' is passed.
   void foo(int x) { ... }

   // static void foo(int x) { ... } // not allowed.  A already has a foo(int)
}

 -- andy
May 27, 2004
In article <c959fd$17un$1@digitaldaemon.com>, Walter says...
>
>
>> First, let's examine what Java does:
>>
>> Applying "this." or "Class.this." prefixes to Java methods does NOT constrain the invocation to the targeted class instance.
>
>Correct,  although I don't believe "Class.this" is valid java syntax.
>
My mistake, the sintax is valid.

in "Class.this"

the "Class" is an outer class or enclosing class,
so not supported in D (I would like to say yet).

Ant


May 27, 2004
In article <c92nkt$2mun$2@digitaldaemon.com>, Walter says...
>
>The way to do that is to have two functions, a "get()" which is virtual
>which calls a private "Aget()". Then, instead of this.get(), use Aget().

I'm afraid that is the correct answer.
if get() if not suppouse to be overwritten make it final or private.
You want to through away one of the main OO design features.
I say that your implementation design should be reviwed, not the language.
is this a real life scenario you need to support?

Ant

>
>"Kris" <someidiot@earthlink.dot.dot.dot.net> wrote in message news:c5ql8n$4ot$1@digitaldaemon.com...
>> Is there a way to specifically invoke a method implemented within the enclosing class? One can explicitly invoke the super class implementation (via 'super.'), but what about this scenario:
>>
>> class A
>> {
>>        private Object[char[]]  map;
>>
>>        Object get (char[] key)
>>        {
>>             return map[key];
>>        }
>>
>>        Object extract (char[] key)
>>        {
>>             // we want to invoke get() from this class;
>>             // not from some subclass implementation
>>             Object o = this.get (key);
>>              if (o)
>>                  delete map [key];
>>              return o;
>>        }
>> }
>>
>>
>> class B : A
>> {
>>       Object get (char[] key)
>>       {
>>             Object o = super.get (key);
>>             // do all kinds of other stuff ...
>>       }
>> }
>>
>> When instantiated as a Class B instance, A.extract() does *not* want to
>> invoke the overridden version of get() ... it just wants to use the known
>> version within its containing class ...
>>
>> Can D handle this case?
>>
>> - Kris
>>
>>
>
>


May 27, 2004
I read the Java spec also, but wrote a wee program to confirm. The compiler/runtime executes as I previously noted.

Please see inlined comments below:

"Walter"  wrote:
> > 5) Walter notes (above) that "Java does not allow this.method() to
access
> > overridden methods".
>
> The relevant wording from the Java spec 8.4.6.2: "A hidden method can be accessed by using a qualified name or by using a method invocation expression (15.11) that contains the keyword super or a cast to a
superclass
> type."


Yes, but I believe "hidden" does not mean overridden in this case; instead, it applies to a method declared as static. This section (below) explicitly states, and shows, that casting does not constrain the override. This is borne out with my testing:

-------------------------------------------
15.12.4.9 Example: Method Invocation using super
An overridden instance method of a superclass may be accessed by using the
keyword super to access the members of the immediate superclass, bypassing
any overriding declaration in the class that contains the method invocation.
When accessing an instance variable, super means the same as a cast of this
(§15.11.2), but this equivalence does not hold true for method invocation.
This is demonstrated by the example:


class T1 {
	String s() { return "1"; }
}
class T2 extends T1 {
	String s() { return "2"; }
}
class T3 extends T2 {
	String s() { return "3"; }
	void test() {
		System.out.println("s()=\t\t"+s());
		System.out.println("super.s()=\t"+super.s());
		System.out.print("((T2)this).s()=\t");
			System.out.println(((T2)this).s());
		System.out.print("((T1)this).s()=\t");
			System.out.println(((T1)this).s());
	}
}
class Test {
	public static void main(String[] args) {
		T3 t3 = new T3();
		t3.test();
	}
}
which produces the output:

s()=					3
super.s()=					2
((T2)this).s()=					3
((T1)this).s()=					3
The casts to types T1 and T2 do not change the method that is invoked,
because the instance method to be invoked is chosen according to the
run-time class of the object referred to be this. A cast does not change the
class of an object; it only checks that the class is compatible with the
specified type.
-----------------------------------


Section 8.4.6.2 says this, which refers to static methods instead:

__________________________
8.4.6.2 Hiding (by Class Methods)
If a class declares a static method, then the declaration of that method is
said to hide any and all methods with the same signature in the superclasses
and superinterfaces of the class that would otherwise be accessible to code
in the class. A compile-time error occurs if a static method hides an
instance method.
In this respect, hiding of methods differs from hiding of fields (§8.3), for
it is permissible for a static variable to hide an instance variable. Hiding
is also distinct from shadowing (§6.3.1) and obscuring (§6.3.2).

A hidden method can be accessed by using a qualified name or by using a method invocation expression (§15.12) that contains the keyword super or a cast to a superclass type. In this respect, hiding of methods is similar to hiding of fields.

--------------------------------------


> > First, let's examine what Java does:
> >
> > Applying "this." or "Class.this." prefixes to Java methods does NOT constrain the invocation to the targeted class instance.
>
> Correct,  although I don't believe "Class.this" is valid java syntax.

I couldn't find it in the spec either, but it was added along with inner-classes, such that the inner class can refer to its parent (as in "ParentClass.this.blah"). Believe me, it compiles and executes just as one would expect. Oh, I didn't mean the literal "Class"; just a class name.


> > Nor does the
> > casting of an instance to a target class.
>
> This is not correct.

See above example from the spec. Casting does work for field access, but it does not constrain overridden methods.

>
> > While field access DOES operate in
> > the manner expected, overridden methods are invoked the same way as
> without
> > the prefix. That is, the only way that Java constrains method overrides
is
> > via the "super." prefix.
>
> Not correct according to the Java spec.

Please see above. Testing bears out the assertion. You cannot rely on the language specs Walter <g>


> > The alternative syntax "typeof(this)." would appear to conflict with the invocation of a static D method.
>
> No, it doesn't. typeof(this).method() is semantically the same as
> ClassName.method(), which gets an implicit 'this' if in a non-static
member
> function.

That's very cool! Thank you. This will be yet another example where D improves the status-quo ...