[M3devel] calling an overridden method
Daniel Alejandro Benavides D.
dabenavidesd at yahoo.es
Thu Jul 21 18:14:52 CEST 2011
Hi all:
I find this terminology of types and checks and inheritance big convoluted here (but would allow me this to say we need a baby toy to plataform independent Modula-3 language or sort of artifact, but not everything we would want since there seems to be pieces of work which are undecidable, how one can create some application of it, it seems odd to try those for me).
Although it is better to start with something to do that and I fact I believe it's already started by a great computologist, Coenraad Bron with work on Pascal, Modular pascal at the University of Twente, The Netherlands and later in Oberon with Modula-3 reusability and typability, at University of Groningen, The Netherlands, after all, Coen Bron, worked hard for that. Indeed people there liked Modula-like languages a lot, which makes sense for yet another local Prof visit there.
I don't know many or too much but I believe great computer scientist came from there as well but certainly is a good resource of efforts in tools and so for ourselves
Thanks in advance
--- El jue, 21/7/11, Mika Nystrom <mika at async.caltech.edu> escribió:
> De: Mika Nystrom <mika at async.caltech.edu>
> Asunto: Re: [M3devel] calling an overridden method
> Para: "Peter McKinna" <peter.mckinna at gmail.com>
> CC: m3devel at elegosoft.com
> Fecha: jueves, 21 de julio, 2011 02:27
> Section 6, under "Designators".
>
> Mika
>
> Peter McKinna writes:
> >--0015174c40fe49b5ad04a88e39c4
> >Content-Type: text/plain; charset=ISO-8859-1
> >
> >Forgive my ignorance, but where in the report does it
> allow A.m(b,xxx)
> >where that A is a type
> >
> >I just compiled it and it works fine but its a
> syntactic subtlety that I
> >have sadly been unaware.
> >
> >Regards Peter
> >
> >On Thu, Jul 21, 2011 at 2:18 AM, Rodney M. Bates <rodney_bates at lcwb.coop>wrote
> >:
> >
> >>
> >>
> >> On 07/20/2011 02:44 AM, Mika Nystrom wrote:
> >>
> >>> Right, a shadowed method is a new method of
> the same name, just like
> >>> Algol block structure. An overridden
> method is a different binding for
> >>> the same method. If you override a
> method, you can't call the old one
> >>> without using the special A.T.m(a,...) syntax,
> since there's no binding
> >>> for the old one within the type record for
> your object. The A.T.m(...)
> >>> syntax works whether the method is shadowed or
> overridden. The widening
> >>> only works for shadowed methods.
> >>>
> >>> The clever thing is that the method dispatch
> is based on the known type
> >>> of the object within the context that the
> method is called, not where the
> >>> object type is declared.
> >>>
> >>> This distinction between overriding and
> shadowing I think is one of the
> >>> most brilliant aspects of Modula-3: it avoids
> the problem that you
> >>> create an unwanted method override by adding a
> new method of the same name
> >>> (whether in a supertype or a subtype).
> >>>
> >>
> >> This is probably my single favorite example of how
> C++ is badly
> >> designed for practical programming and, more
> generally, why syntactic
> >> explicitness is important.
> >>
> >> C++ has both overrides and new methods, but it is
> *very* hard for a
> >> programmer to see the difference.
> Syntactically, they look identical.
> >>
> >> For a member function declaration to be an
> override, you need:
> >> 1) It has the same simple name as the original.
> >> 2) It has an equivalent signature to the
> original.
> >> 3) The original is 'virtual', which in this
> context means overridable.
> >>
> >> Equivalence of signatures is complicated, as there
> are several rules
> >> about selected ways they can differ and still be
> equivalent. For
> >> example, int *p and int p[] are equivalent.
> There can be overloaded
> >> (same name, different signatures) original
> methods, from the same or
> >> different superclasses, to be considered.
> And then this allows what
> >> would, I suppose, be called "overloaded
> overrides", as well as a mix
> >> of overloaded new methods and overrides, all with
> the same name.
> >>
> >> 'virtual' has at least two very different
> meanings, one relevant here
> >> and one regarding repeated inheritance over
> multiple paths. The
> >> virtual property can come from anywhere in the
> inheritance hierarchy,
> >> and can change between the original method
> declaration and the
> >> subclass we are trying to read.
> >>
> >> Shadowing can also involve signature equivalence
> as well as name
> >> equality. AFAIK, you can't shadow with the
> same name and signature,
> >> if the relevant inherited method is virtual.
> But if not, a same-name,
> >> signature-equivalent member function is a shadow.
> >>
> >> Meanwhile, linking up to a precursor to be
> overridden involves looking
> >> at signatures of same-named methods from all
> superclasses, whereas
> >> overload resolution in calls considers only
> same-named candidates from
> >> the same class, before signatures are considered.
> >>
> >> The interactions with static member functions make
> things even more
> >> complicated.
> >>
> >> None of this is syntactically explicit. In
> contrast, Modula-3 says
> >> either "METHODS" or "OVERRIDES" explicitly.
> Moreover, even without
> >> these tags, new methods always have signatures,
> while overrides do
> >> not.
> >>
> >> In my experience, very few C++ programmers,
> outside of compiler
> >> writers and language committee members, understand
> these semantic
> >> rules. And they do predictably get surprised
> when something turns out
> >> to dispatch when they expected it not to or vice
> versa. When this
> >> happens, rather than figure the language out, they
> just make a note to
> >> self to use some coding convention that avoids
> getting anywhere close,
> >> e.g., never using the same name for different
> methods, only for
> >> overrides. (Well, OK, that's probably a good
> practice anyway, but you
> >> see my point, I think.)
> >>
> >>
> >>
> >>> Mika
> >>>
> >>>
> >>> Hendrik Boom writes:
> >>>
> >>>> On Tue, Jul 19, 2011 at 01:26:14PM -0400,
> Hendrik Boom wrote:
> >>>>
> >>>>> On Tue, Jul 19, 2011 at 07:11:05AM
> -0700, Mika Nystrom wrote:
> >>>>>
> >>>>>> Sorry I'm being confusing here.
> >>>>>>
> >>>>>> The code is right but I think your
> question is a bit confusing.
> >>>>>>
> >>>>>> With your init example I don't
> think you're talking about an overridden
> >>>>>> init method but a shadowed
> method.
> >>>>>>
> >>>>>
> >>>>> A 'shadowed' method. Is that
> what you call what's essentially a new
> >>>>> method that happens to have the same
> name? Just like the way a variable
> >>>>> in a nested block that has the same
> name as one in an outer block would
> >>>>> be a new variable (I'm not sure Modula
> 3 allows this, the way C and the
> >>>>> Algols do; I find it leads to
> confusing code).
> >>>>>
> >>>>> Init is the one I've seen explained in
> documentation. It's not what I
> >>>>> want, because that trick provides no
> inheritance.
> >>>>>
> >>>>> You can't call an overridden
> method
> >>>>>> through the widening trick, but
> you *can* call a shadowed method like
> >>>>>> that.
> >>>>>>
> >>>>>> Mika
> >>>>>>
> >>>>>> Mika Nystrom writes:
> >>>>>>
> >>>>>>>
> >>>>>>> TYPE A = OBJECT METHODS m(xxx)
> END;
> >>>>>>>
> >>>>>>> TYPE B = A OBJECT METHODS
> m(xxx) END;
> >>>>>>>
> >>>>>>
> >>>>> This is, if I understand the
> terminology, a declaratin of m as a shadowd
> >>>>> method. It's not what I want,
> because I intend that under normal
> >>>>> circumstances, if an B object is used
> in a context where its static type
> >>>>> is known as A, I still want the normal
> overriding mechanism to ensure
> >>>>> that B's m is the one called.
> >>>>>
> >>>>> I mean something like
> >>>>>
> >>>>> TYPE B = A OBJECT OVERRIDES m := ...
> END;
> >>>>>
> >>>>>
> >>>>>>> b := NEW(B);
> >>>>>>>
> >>>>>>> A.m(b,xxx)
> >>>>>>>
> >>>>>>
> >>>>> So this is a way to specifically get
> the m that belongs with A? Will
> >>>>> this work with the way I want to
> define B and m?
> >>>>>
> >>>>> as in
> >>>>>
> >>>>> TYPE A = OBJECT METHODS m(xxx) := bar
> END;
> >>>>>
> >>>>> TYPE B = A OBJECT OVERRIDES m := foo
> END;
> >>>>>
> >>>>> PROCEDURE foo(self : B, ....) =
> >>>>> BEGIN
> >>>>> ...
> >>>>> ...
> >>>>> A.m(self,
> ...) (* and this ends up calling bar? *)
> >>>>> ...
> >>>>> END foo;
> >>>>>
> >>>>
> >>>> Well. I tried my version, and it
> works. Thanks for the advice.
> >>>>
> >>>> -- hendrik
> >>>>
> >>>>
> >>>>>
> >>>>>>> Mika
> >>>>>>>
> >>>>>>> Hendrik Boom writes:
> >>>>>>>
> >>>>>>>> I have a module containing
> a parent class, and another containing a
> >>>>>>>> child class.
> >>>>>>>>
> >>>>>>>> The parent class contains
> a method 'foo', which is to be overridden
> >>>>>>>> in
> >>>>>>>> the child class.
> >>>>>>>>
> >>>>>>>> But in implementing 'foo'
> in the child class I want to call the
> >>>>>>>> parent's
> >>>>>>>>
> >>>>>>>
> >>>> method.
> >>>>>>>>
> >>>>>>>> Now with the method 'init'
> there's a trick where in the child's init,
> >>>>>>>> you WIDEN self to the
> parent's type and then call its init.
> >>>>>>>> This works because 'init'
> isn't overridden in an OVERRIDES clause,
> >>>>>>>> but is defined as a new
> method that happens to have the same name.
> >>>>>>>>
> >>>>>>>> Is there any way to do
> this with 'foo', where the whole point is that
> >>>>>>>> it be an overridden method
> and not a new one?
> >>>>>>>>
> >>>>>>>> Do I have to do something
> like covertly exporting the PROCEDURE that
> >>>>>>>> implements 'foo' in the
> parent's module so that it can be called
> >>>>>>>> directly? That would seem
> to be a violation of modular design. Or is
> >>>>>>>> violating modular design
> exactly what I'm really trying to do here?
> >>>>>>>>
> >>>>>>>> -- hendrik
> >>>>>>>>
> >>>>>>>
> >>>
> >
> >--0015174c40fe49b5ad04a88e39c4
> >Content-Type: text/html; charset=ISO-8859-1
> >Content-Transfer-Encoding: quoted-printable
> >
> >Forgive my ignorance, but where in the report does it
> allow A.m(b,xxx)=A0 w=
> >here 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=3D"gmail_quote">On Thu, Jul
> 21, 2011 at 2:18 AM, Rodney M. B=
> >ates <span dir=3D"ltr"><<a
> href=3D"mailto:rodney_bates at lcwb.coop">rodney=
> >_bates at lcwb.coop</a>></span>
> wrote:<br><blockquote class=3D"gmail_quote"=
> > style=3D"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=3D"gmail_quote"
> style=3D"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. =A0An overridden method is a
> different binding for<b=
> >r>
> >the same method. =A0If you override a method, you
> can't call the old on=
> >e<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.
> =A0The A.T.m(...)<b=
> >r>
> >syntax works whether the method is shadowed or
> overridden. =A0The 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<b=
> >r>
> >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. =A0Syntactically,
> 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 overridab=
> >le.<br>
> ><br>
> >Equivalence of signatures is complicated, as there are
> several rules<br>
> >about selected ways they can differ and still be
> equivalent. =A0For<br>
> >example, int *p and int p[] are equivalent. =A0There
> can be overloaded<br>
> >(same name, different signatures) original methods,
> from the same or<br>
> >different superclasses, to be considered. =A0And 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 he=
> >re<br>
> >and one regarding repeated inheritance over multiple
> paths. =A0The<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. =A0AFAIK, you can't shadow with the same
> name and signature,<=
> >br>
> >if the relevant inherited method is virtual. =A0But 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. =A0In contrast,
> Modula-3 says<br>
> >either "METHODS" or
> "OVERRIDES" explicitly. =A0Moreover=
> >, 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. =A0And they do predictably get surprised when
> something turns out<br=
> >>
> >to dispatch when they expected it not to or vice versa.
> =A0When 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<b=
> >r>
> >see my point, I think.)<br>
> ><br>
> ><br>
> ><blockquote class=3D"gmail_quote"
> style=3D"border-left: 1px solid rgb(204, =
> >204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left:
> 1ex;">
> ><br>
> > =A0 =A0 =A0Mika<br>
> ><br>
> ><br>
> >Hendrik Boom writes:<br>
> ><blockquote class=3D"gmail_quote"
> style=3D"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=3D"gmail_quote"
> style=3D"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=3D"gmail_quote"
> style=3D"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 overri=
> >dden<br>
> >init method but a shadowed method.<br>
> ></blockquote>
> ><br>
> >A 'shadowed' method. =A0Is that what you call
> what's essentiall=
> >y a new<br>
> >method that happens to have the same name? =A0Just 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. =A0It's =A0no=
> >t what I<br>
> >want, because that trick provides no
> inheritance.<br>
> ><br>
> ><blockquote class=3D"gmail_quote"
> style=3D"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>
> > =A0 =A0 =A0Mika<br>
> ><br>
> >Mika Nystrom writes:<br>
> ><blockquote class=3D"gmail_quote"
> style=3D"border-left: 1px solid rgb(204, =
> >204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left:
> 1ex;">
> ><br>
> >TYPE A =3D OBJECT METHODS m(xxx) END;<br>
> ><br>
> >TYPE B =3D 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. =A0It's not what I want, because I
> =A0intend 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 =3D A OBJECT OVERRIDES m :=3D ...
> END;<br>
> ><br>
> ><blockquote class=3D"gmail_quote"
> style=3D"border-left: 1px solid rgb(204, =
> >204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left:
> 1ex;"><blockquote class=
> >=3D"gmail_quote" style=3D"border-left: 1px solid
> rgb(204, 204, 204); margin=
> >: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
> >
> ><br>
> >b :=3D 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? =A0Will<br>
> >this work with the way I want to define B and
> m?<br>
> ><br>
> >as in<br>
> ><br>
> >TYPE A =3D OBJECT METHODS m(xxx) :=3D bar
> END;<br>
> ><br>
> >TYPE B =3D A OBJECT OVERRIDES m :=3D foo
> END;<br>
> ><br>
> >PROCEDURE foo(self : B, ....) =3D<br>
> >BEGIN<br>
> > =A0 ...<br>
> > =A0 ...<br>
> > =A0 =A0A.m(self, ...) =A0 (* and this ends up calling
> bar? *)<br>
> > =A0 ...<br>
> >END foo;<br>
> ></blockquote>
> ><br>
> >Well. I tried my version, and it works. =A0Thanks for
> the advice.<br>
> ><br>
> >-- hendrik<br>
> ><br>
> ><blockquote class=3D"gmail_quote"
> style=3D"border-left: 1px solid rgb(204, =
> >204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left:
> 1ex;">
> ><br>
> ><blockquote class=3D"gmail_quote"
> style=3D"border-left: 1px solid rgb(204, =
> >204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left:
> 1ex;"><blockquote class=
> >=3D"gmail_quote" style=3D"border-left: 1px solid
> rgb(204, 204, 204); margin=
> >: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
> >
> ><br>
> > =A0 =A0 =A0Mika<br>
> ><br>
> >Hendrik Boom writes:<br>
> ><blockquote class=3D"gmail_quote"
> style=3D"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 par=
> >ent's<br>
> ></blockquote></blockquote></blockquote></blockquote>
> ><br>
> ><blockquote class=3D"gmail_quote"
> style=3D"border-left: 1px solid rgb(204, =
> >204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left:
> 1ex;"><blockquote class=
> >=3D"gmail_quote" style=3D"border-left: 1px solid
> rgb(204, 204, 204); margin=
> >: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
> ><blockquote class=3D"gmail_quote"
> style=3D"border-left: 1px solid rgb(204, =
> >204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left:
> 1ex;"><blockquote class=
> >=3D"gmail_quote" style=3D"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&#=
> >39;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 clau=
> >se,<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 th=
> >at<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 calle=
> >d<br>
> >directly? That would seem to be a violation of modular
> design. =A0Or 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>
> >
> >--0015174c40fe49b5ad04a88e39c4--
>
More information about the M3devel
mailing list