Forgive my ignorance, but where in the report does it allow A.m(b,xxx)  where that A is a type<br><br>I just compiled it and it works fine but its a syntactic subtlety that I have sadly been unaware.<br><br>Regards Peter<br>
<br><div class="gmail_quote">On Thu, Jul 21, 2011 at 2:18 AM, Rodney M. Bates <span dir="ltr"><<a href="mailto:rodney_bates@lcwb.coop">rodney_bates@lcwb.coop</a>></span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>
<br>
On 07/20/2011 02:44 AM, Mika Nystrom wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Right, a shadowed method is a new method of the same name, just like<br>
Algol block structure.  An overridden method is a different binding for<br>
the same method.  If you override a method, you can't call the old one<br>
without using the special A.T.m(a,...) syntax, since there's no binding<br>
for the old one within the type record for your object.  The A.T.m(...)<br>
syntax works whether the method is shadowed or overridden.  The widening<br>
only works for shadowed methods.<br>
<br>
The clever thing is that the method dispatch is based on the known type<br>
of the object within the context that the method is called, not where the<br>
object type is declared.<br>
<br>
This distinction between overriding and shadowing I think is one of the<br>
most brilliant aspects of Modula-3: it avoids the problem that you<br>
create an unwanted method override by adding a new method of the same name<br>
(whether in a supertype or a subtype).<br>
</blockquote>
<br>
This is probably my single favorite example of how C++ is badly<br>
designed for practical programming and, more generally, why syntactic<br>
explicitness is important.<br>
<br>
C++ has both overrides and new methods, but it is *very* hard for a<br>
programmer to see the difference.  Syntactically, they look identical.<br>
<br>
For a member function declaration to be an override, you need:<br>
1) It has the same simple name as the original.<br>
2) It has an equivalent signature to the original.<br>
3) The original is 'virtual', which in this context means overridable.<br>
<br>
Equivalence of signatures is complicated, as there are several rules<br>
about selected ways they can differ and still be equivalent.  For<br>
example, int *p and int p[] are equivalent.  There can be overloaded<br>
(same name, different signatures) original methods, from the same or<br>
different superclasses, to be considered.  And then this allows what<br>
would, I suppose, be called "overloaded overrides", as well as a mix<br>
of overloaded new methods and overrides, all with the same name.<br>
<br>
'virtual' has at least two very different meanings, one relevant here<br>
and one regarding repeated inheritance over multiple paths.  The<br>
virtual property can come from anywhere in the inheritance hierarchy,<br>
and can change between the original method declaration and the<br>
subclass we are trying to read.<br>
<br>
Shadowing can also involve signature equivalence as well as name<br>
equality.  AFAIK, you can't shadow with the same name and signature,<br>
if the relevant inherited method is virtual.  But if not, a same-name,<br>
signature-equivalent member function is a shadow.<br>
<br>
Meanwhile, linking up to a precursor to be overridden involves looking<br>
at signatures of same-named methods from all superclasses, whereas<br>
overload resolution in calls considers only same-named candidates from<br>
the same class, before signatures are considered.<br>
<br>
The interactions with static member functions make things even more<br>
complicated.<br>
<br>
None of this is syntactically explicit.  In contrast, Modula-3 says<br>
either "METHODS" or "OVERRIDES" explicitly.  Moreover, even without<br>
these tags, new methods always have signatures, while overrides do<br>
not.<br>
<br>
In my experience, very few C++ programmers, outside of compiler<br>
writers and language committee members, understand these semantic<br>
rules.  And they do predictably get surprised when something turns out<br>
to dispatch when they expected it not to or vice versa.  When this<br>
happens, rather than figure the language out, they just make a note to<br>
self to use some coding convention that avoids getting anywhere close,<br>
e.g., never using the same name for different methods, only for<br>
overrides. (Well, OK, that's probably a good practice anyway, but you<br>
see my point, I think.)<br>
<br>
<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>
      Mika<br>
<br>
<br>
Hendrik Boom writes:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
On Tue, Jul 19, 2011 at 01:26:14PM -0400, Hendrik Boom wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
On Tue, Jul 19, 2011 at 07:11:05AM -0700, Mika Nystrom wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Sorry I'm being confusing here.<br>
<br>
The code is right but I think your question is a bit confusing.<br>
<br>
With your init example I don't think you're talking about an overridden<br>
init method but a shadowed method.<br>
</blockquote>
<br>
A 'shadowed' method.  Is that what you call what's essentially a new<br>
method that happens to have the same name?  Just like the way a variable<br>
in a nested block that has the same name as one in an outer block would<br>
be a new variable (I'm not sure Modula 3 allows this, the way C and the<br>
Algols do; I find it leads to confusing code).<br>
<br>
Init is the one I've seen explained in documentation.  It's  not what I<br>
want, because that trick provides no inheritance.<br>
<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
You can't call an overridden method<br>
through the widening trick, but you *can* call a shadowed method like<br>
that.<br>
<br>
      Mika<br>
<br>
Mika Nystrom writes:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>
TYPE A = OBJECT METHODS m(xxx) END;<br>
<br>
TYPE B = A OBJECT METHODS m(xxx) END;<br>
</blockquote></blockquote>
<br>
This is, if I understand the terminology, a declaratin of m as a shadowd<br>
method.  It's not what I want, because I  intend that under normal<br>
circumstances, if an B object is used in a context where its static type<br>
is known as A, I still want the normal overriding mechanism to ensure<br>
that B's m is the one called.<br>
<br>
I mean something like<br>
<br>
TYPE B = A OBJECT OVERRIDES m := ... END;<br>
<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">

<br>
b := NEW(B);<br>
<br>
A.m(b,xxx)<br>
</blockquote></blockquote>
<br>
So this is a way to specifically get the m that belongs with A?  Will<br>
this work with the way I want to define B and m?<br>
<br>
as in<br>
<br>
TYPE A = OBJECT METHODS m(xxx) := bar END;<br>
<br>
TYPE B = A OBJECT OVERRIDES m := foo END;<br>
<br>
PROCEDURE foo(self : B, ....) =<br>
BEGIN<br>
   ...<br>
   ...<br>
    A.m(self, ...)   (* and this ends up calling bar? *)<br>
   ...<br>
END foo;<br>
</blockquote>
<br>
Well. I tried my version, and it works.  Thanks for the advice.<br>
<br>
-- hendrik<br>
<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">

<br>
      Mika<br>
<br>
Hendrik Boom writes:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
I have a module containing a parent class, and another containing a<br>
child class.<br>
<br>
The parent class contains a method 'foo', which is to be overridden in<br>
the child class.<br>
<br>
But in implementing 'foo' in the child class I want to call the parent's<br>
</blockquote></blockquote></blockquote></blockquote>
<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">

method.<br>
<br>
Now with the method 'init' there's a trick where in the child's init,<br>
you WIDEN self to the parent's type and then call its init.<br>
This works because 'init' isn't overridden in an OVERRIDES clause,<br>
but is defined as a new method that happens to have the same name.<br>
<br>
Is there any way to do this with 'foo', where the whole point is that<br>
it be an overridden method and not a new one?<br>
<br>
Do I have to do something like covertly exporting the PROCEDURE that<br>
implements 'foo' in the parent's module so that it can be called<br>
directly? That would seem to be a violation of modular design.  Or is<br>
violating modular design exactly what I'm really trying to do here?<br>
<br>
-- hendrik<br>
</blockquote></blockquote></blockquote></blockquote></blockquote>
<br>
</blockquote>
</blockquote></div><br>