[E-Lang] pending revision of E in a Walnut
Mark S. Miller
markm@caplet.com
Sun, 26 Aug 2001 18:59:05 -0700
At 04:10 PM Sunday 8/26/01, Marc Stiegler wrote:
>In E, the class declaration
>
>class objMaker() :type {...}
>
>is just syntactic shorthand for
>
>def objMaker {
> to new() :type {...}
>}
The expansion is actually more complicated, in order to allow another
"class" to "inherit" from objMaker. The actual expansion is explained at
http://www.erights.org/elang/blocks/inheritance.html . However, if objMaker
does not internally use the variable name "self", then the expansion is
equivalent to the above, with the only remaining difference being that
objMaker also responds to an "adopt" message with one more argument than
the "new" message (the first "self" argument) which would then be ignored,
and otherwise be equivalent to "new".
>So you can virtualize it just the way you virtualize anything else, and
>properties of initialization work the same way they work for anything else.
Correct.
>> Second, I wonder whether there aren't security implications of treating
>> the arguments to the constructor as instance variables. Does this make it
>> easy to forget to make copies of them? Will this lead to subtle problems
>> with wall-banging or other kinds of leakage, since the object the client
>> supplied is known to be the one held by the object?
>
>I haven't seen a security issue with it. [...]
I am also failing to understand what you might be worried about here.
Please try again?
>> Under "Inheritance", you say "Some experts consider inheritance to be a
>> dangerous feature of programming languages [...]". Does this statement
>> apply only to implementation inheritance? Because I consider type
>> inheritance to be the root of polymorphism, which seems to me to be the
>> source of most of the power and benefits of OOP.
Before answering, I'd like to change this terminology.
"Type inheritance" is a peculiar notion that I find confusing. Instead,
there is "subtyping", as when one Java interface extends another. And there
is "runtime polymorphism", as when several different implementation can
implement the same type, and the same message send in the code can invoke
different methods depending on the runtime implementation (or class, but not
type!) of the object. In Java, this happens when several classes implement
a method declared in a supertype. (Ignore that, in Java, the supertype may
be either a class or interface declaration.)
"Implementation inheritance" is a fine term for what I would normally just
call "inheritance", but in this note I'll say "implementation inheritance"
to avoid confusion. This is happens in Java when one class extends another,
and uses some of the *behavior* defined by the superclass to provide its own
behavior.
E does not really have declared types, so it doesn't really have declared
subtyping. However, E has gobs of runtime polymorphism. Not having
declared types, E's polymorphism is name-based, as is Smalltalk's. In
Smalltalk, the method name also determines the arity of the message. In E
it does not, so E polymorphism and method dispatch is based on the name and
arity of the message.
(Hal Finney has pointed out that there's a security price to be paid by
using name-based, rather than type-based polymorphism. (See his analysis of
the flaws in the ERTP-aware MintMaker code.) These are not fatal, but do
require more care in order to avoid falling into these pits. Fortunately or
unfortunately, having set out on the non-statically-typed rapid prototyping
path of language design, we must learn to live with this weakness rather
than avoiding it. I believe this cost is still cheaper than strong typing,
but would be happy were someone to create a strongly typed E derivative that
proves me wrong.)
>> Later in that paragraph you say "none of the full-blown examples in this
>> book actually use inheritance."
I distinguish between simple delegation and full blown implementation
inheritance according to whether there is a message pathway analogous to the
"self" pointers shown in the diagram on
http://www.erights.org/elang/blocks/inheritance.html . Delegation allows
the derived behavior to make use of the base behavior. The "self" pathway
enables this base behavior to in turn be parameterized (typically by
overriding, but see Beta) by further derived behavior, as in the example's
getFoo().
(Btw, by my earlier definitions, even simple delegation is a form of
implementation inheritance. I'm happy with that, so long as we distinguish
it from full blown (or classic) implementation inheritance, which should
usually be avoided.)
>I guess that reminds me that I haven't seen much use of polymorphism.
Strange, and an artifact of choosing small examples. E is as pervasively
polymorphic as Smalltalk.
> (Other than in the coordinate spaces code
>> MarkM sent as part of a different discussion, but I haven't figured out
>> how that works yet.)
Let's do lunch.
>> I realize that E doesn't have strong typing, but if
>> it also deemphasizes polymorphic types, I'm likely to be disappointed.
Don't worry! Be happy!
>> Why is this section here? Do you have an aversion to type hierarchies or to
>> polymorphism? If not, I'd suggest being clear what aspect of inheritance
>> you're advising people to avoid. If that is the point, I'd like to hear
>> what I've been doing wrong all these years. :-)
>
>It's the type hierarchies that cause religious wars here in the e-lang list.
>In E in a Walnut, if you just search for each usage of "delegate {", each of
>those is, I believe, a usage of polymorphism.
Terminology confusion. Each of those is a usage of delegation. MarcS, how
about an explicit example of runtime polymorphism in the next Walnut?
The book is advising against usage of the "adopt" / "self" notions provided
by the class sugar, or patterns of delegation morally equivalent to these.
Where inheritance is normally used, delegation + explicit parameterization
(rather than overriding) is usually better.
Since programming in E, I have come across exactly one example for which
classic inheritance is exactly the right pattern: specializing a copy
visitor. I'll leave that one to another email message.
Cheers,
--MarkM