[E-Lang] Re: inheritance, delegation, mental models for begin
ners (was: down with `define' (was: newbie syntax: picayune points from a
prejudiced programmer))
Karp, Alan
alan_karp@hp.com
Fri, 2 Mar 2001 17:20:56 -0800
MarkM wrote:
>
> Btw, many of us, when doing class-based programming with inheritance,
mostly
> stopped using concrete non-final classes since the Udanax Gold days. When
> we found we wanted to subclass a concrete class, we refactored so that we
> were subclassing from an abstract class. I believe Dean was always the
> biggest advocate of this design rule. The E implementation grossly
violates
> this, but that's only because of Java used to have a horrendous huge
> per-class memory cost. (It may still, but we should fix this anyway,
since
> memory is now cheaper.)
I must have been doing something wrong, because I tried to do this (at least
I think I did), and I didn't like the result. Say I have a class C with 2
methods, M1 and M2. One subclass C1 overrides M1, another C2 overrides M2.
If C is a concrete class, then C1 gets C's M2, and C2 gets C's M1. If C is
abstract in that it has no implementation for M1 and M2, where do these
implementations go? I ended up with an extra abstract class between C and
each of C1 and C2. Of course, it's not terrible with only 2 methods; my
case had 5.
_________________________
Alan Karp
Principal Scientist
Decision Technology Department
Hewlett-Packard Laboratories MS 1U-2
1501 Page Mill Road
Palo Alto, CA 94304
(650) 857-3967, fax (650) 857-6278
https://ecardfile.com/id/Alan_Karp
http://www.hpl.hp.com/personal/Alan_Karp/
> -----Original Message-----
> From: Mark S. Miller [mailto:markm@caplet.com]
> Sent: Friday, March 02, 2001 3:56 PM
> To: Marc Stiegler
> Cc: zooko@zooko.com; Tyler Close; Ka-Ping Yee; e-lang@eros-os.org;
> dworkin@dworkin.nl
> Subject: Re: [E-Lang] Re: inheritance, delegation, mental models for
> beginners (was: down with `define' (was: newbie syntax:
> picayune points
> from a prejudiced programmer))
>
>
> At 11:01 AM Friday 3/2/01, Marc Stiegler wrote:
> >[With inheritance] if the subclass overrides a
> >method in the superclass, when the superclass calls that
> method it goes back
> >out to the subclass's method. With delegation, a
> delegated-to class call to
> >the overridden method is directed to the delegated-to class
> implementation.
>
> As Dean's message reveals, I may be badly out of touch with
> how the world
> uses terms these days. However, my use of these terms agrees
> with MarcS's,
> which I believe agrees with the website and the list.
> Therefore, when you say
>
> > The MUD programming languages [...] use the word
> > "inheritance" to mean the thing that we call "delegation".
>
> followed by
>
> > Since E is dynamically typed there is no really important
> difference, is
> > there? [2]
>
> since the second doesn't correspond to our usage, I remain
> curious about
> what MUD programmers actually do mean by "inheritance".
>
> Regarding academia's use of these terms, perhaps the
> definitive document is
> the Treaty of Orlando
> http://lieber.www.media.mit.edu/people/lieber/Lieberary/OOP/Tr
> eaty/Treaty.ps
>
>
> >In fact, I have thought about designs for a few programs for which
> >inheritance would make the system easier to understand and
> maintain, [...]
>
> I've got one for you: the shamefully undocumented CopyVisitor
> from within
> the E language implementation
> http://www.erights.org/javadoc/org/erights/e/elang/visitors/Co
> pyVisitor.html .
>
> Given a tree of typed nodes, such as Kernel-E parse trees, we
> know that
> we'll want to write several algorithms for walking such trees
> and returning
> similar trees derived from these trees by some
> transformation. The current
> E language implementation has three such tree transformers:
> RenameVisitor,
> AlphaRenameVisitor, and SubstVisitor. For all of these, for
> most of the
> types of parse nodes, they simply want to copy that parse node while
> *filling in the likewise transformed version* of the children
> of that parse
> node.
>
> The copying behavior they have in common is implemented by
> the CopyVisitor.
> The CopyVisitor is carefully written so that it can be reused in an
> equivalent fashion whether by Java-style
> class-based-inheritance, or by
> E-style inheritance-by-static-delegation
> http://www.erights.org/elang/blocks/inheritance.html .
>
> The familiar class-based description first:
>
> The actual RenameVisitor is implemented in Java as a subclass of
> CopyVisitor. It overrides those methods it needs to change,
> but not the
> others. For these others, CopyVisitor's copying behavior is
> used, which
> first *calls itself* to make a copy of the children of the node being
> copied, and then makes a copy of the current node using these copied
> children. Of course, the "itself" above is actually a
> RenameVisitor rather
> than a pure CopyVisitor, so these children contain
> transformed copies of the
> original children.
>
> The equivalent instance-based delegation description:
>
> RenameVisitor could have been implemented in E as follows:
>
> def newRenameVisitor(renamings) :any {
> def self := {
> def super := newCopyVisitor(self)
>
> def RenameVisitor {
> to visitCatchExpr(...) :any { ... }
> //... likewise for all parse node types
> // needing transformation...
>
> delegate { super }
> }
> }
> }
>
> CopyVisitor could have been implemented in E as:
>
> def newCopyVisitor(self) :any {
> def CopyVisitor {
> to visitCallExpr(recip, verb, args) :any {
> def transformedRecip := recip welcome(self)
> //... transform args ...
> newCallExpr(transformedRecip, verb, transformedArgs)
> }
> //... other parse node types ...
> }
> }
>
> This can be seen as a combination of visitor and decoration,
> or we can just
> name this pattern "inheritance", since it exactly produces (with
> instance-based delegation) the semantics associated with class-based
> inheritance.
>
> Given that we keep "delegate", notice how the "class"
> construct provides us
> no additional help with the above code. Why? Because
> RenameVisitor is (in
> Java terminology) concrete and final, while CopyVisitor is
> essentially
> abstract. The class construct only helps in defining the
> equivalent of
> classes that are concrete and non-final. The price of
> leaving out the
> "class" construct is only that it becomes four lines more
> difficult to write
> one object-maker that supports both direct instantiation and
> inheriting (be
> delegation) from the objects it creates.
>
> Btw, many of us, when doing class-based programming with
> inheritance, mostly
> stopped using concrete non-final classes since the Udanax
> Gold days. When
> we found we wanted to subclass a concrete class, we
> refactored so that we
> were subclassing from an abstract class. I believe Dean was
> always the
> biggest advocate of this design rule. The E implementation
> grossly violates
> this, but that's only because of Java used to have a horrendous huge
> per-class memory cost. (It may still, but we should fix this
> anyway, since
> memory is now cheaper.)
>
> So my current inclination is to leave out the "class"
> construct, go with
> MarcS's definition of "inheritance", rather than Zooko's and
> to truthfully
> observe that E supports inheritance perfectly well. And then
> expand on this
> in the Walnut, including the qualifier about concrete
> non-final classes.
>
>
> On a different and depressing note, in writing the above
> code, I noticed a
> reason not to use the "newThing" convention: I first wrote
>
> def newRecip := recip welcome(self)
>
> and then I caught myself. I think this mistake will always
> be natural.
> Better not to have a convention that conflicts with the above
> line. But I
> really dislike "classThing". I like "ThingClass" only
> slightly better. Are you
> sure you don't like the current "ThingMaker"? Instead of
> either pretending
> it's all just classes, or throwing them into the deep end of lambda
> concepts, can't we introduce Makers by saying:
>
> >Makers in E are like classes. You define one as follows.
> [all Makers have
> >a "Maker" suffix on their name.] You use one as follows:
> >
> > def foo := ThingMaker(...)
>
>
> Only later need we reveal that the ThingMaker pattern is only
> a pattern, not
> class-like magic.
>
>
>
> Cheers,
> --MarkM
>
> _______________________________________________
> e-lang mailing list
> e-lang@mail.eros-os.org
> http://www.eros-os.org/mailman/listinfo/e-lang
>