Restricting super calls to inherited method

Paul Fernhout pdfernhout at kurtz-fernhout.com
Sat May 19 22:00:52 UTC 2001


Andrew-

Thanks for the note.

"Andrew P. Black" wrote:
> 
> Dear Paul:
> 
> I don't fully understand all of the motivation for wanting to
> restrict super-send to the same method that is doing the sending.
> And I'm not therefore going to argue against what you are proposing.

What I am trying to get at here is effectively decoupling "algorithm
inheritance" from "class inheritance". Or to put it another way,
thinking in terms of variants of an algorithm which cooperate to be able
to do a variety of tasks is a somewhat different concept than thinking
in terms of a variety of classes along a line in a hierarchy cooperating
to do a task. If the two concepts are separated, by restricting "super"
to just calling methods of the same name, then other optimizations may
become possible. Granted there may have other drawbacks (although I
think tools can help manage the issue.) But it looks like there then is
nothing directly standing in the way of making a Smalltalk-like system
work with a restricted super (especially with your generalized idea from
another note). I think it is still a good question of how much this will
reduce the pleasure of Smalltalk programming -- if at all. I think it
might increase it actually, by eliminating a source of potential
confusion. But my main exploration is whether the idea can lead to an
alternate way of dispatching methods.

> But here are a couple of things to consider.
> 
> First, "Scandinavian Inheritance" (as in Beta), in addition to
> working top-down rather than bottom up, also enforces the restriction
> that you mention: only methods with the same name can inherit.

So, proof of concept. Great.

> Second, if Squeak were concerned with the overhead of message send,
> then we might add an early bound procedure call instruction to the VM
> instruction set.  We could then replace every super-send with a
> procedure call to the statically known method in the superclass.
> 
> We could also do a little bit of class inference, and in cases like
> 
>         c := OrderedCollection new.
>         c add: anObject.
>         c add: anotherObject.
> 
> replace the last to message sends with procedure calls to the methods
> in the (inferred) class OrderedCollection.  More sophisticated
> inference eliminates more sends.
> 
> Why don't we do this?  One major downside cost is that it becomes
> much harder to modify the system.  That is, adding a class or a
> methods almost anywhere can possibly invalidate this sort of
> optimization almost anywhere else.  I'm sure that it is possible to
> track all of the dependencies, and recompile large chunks of the
> system -- but I think that we would loose a great deal of simplicity,
> elegance and speed in making modifications.  This is one of the great
> strengths of Smalltalk.
>
> Instead, we use techniques like the method cache to make method calls fast.

Good points. I don't disagree. But, I'm still curious if the alternate
has been tried in Smalltalk-like systems.
 
> Third, there has been quite a lot of academic work focused on
> eliminating dynamic method search by representing messages as small
> integers, using indexing or hashing, etc.  These techniques can be
> quite useful if you are downloading a closed set of classes and
> methods into a thermostat or a cell phone.  They are not so useful in
> an "open-world" system where new classes and and methods can arrive
> while the system is running, because it may be necessary to re-hash,
> or re-allocate the index numbers.

OK. I need to separate the two issues then -- one is having method
inheritance ("algorithmic specialization" one might call it.) The other
is taking advantage of tables rather than dictionaries for dispatch. The
two aren't completely connected, although one does help enable the
other.

> One final thought to close.  Many years ago I did implement a
> classless object system (Emerald).  In many ways it was very elegant:
> each object owned its own methods as well as its own instance
> variables.  Factories (objects that created other objects) could be
> built just by nesting object constructors.  This solved the
> initialization problem that Smalltalk and Java both have, because the
> constructor for the new object was nested inside the factory method,
> and therefore had access to its state.   Also, singleton objects were
> really simple!

Sounds cool!

> But when we got down to the implementation, we still needed a place
> to put the methods.  Obviously, we did not really want a separate
> copy of the methods in every object that was made in the same
> factory, at least, not if they were on the same machine!  We wanted
> to share the methods.  We also wasted to share things like the
> templates that told the garbage collector and the migration subsystem
> where the pointers were in an object.  So we created an object to
> hold all of this stuff.  Those familiar with Smalltalk will notice
> that there is a name for the object that defines the data layout and
> holds the methods for a bunch of similar objects -- we call it a
> class!  In other words, Emerald actually has class-like objects in
> its implementation, even though they are not present in the language
> syntax.
> 
> I have always been a bit frustrated by this, and came to the
> conclusion that, if we can't get rid of classes from the
> implementation, we shouldn't try to get rid of them from the
> language.   Note that this is an "if - then" argument.  If you _can_
> figure out how to not have "class-like things by another name" in the
> implementation, then it does not apply.

Yes, great point. I worked some with NewtonScript and you have to put
your code somewhere! Even in Self, I think instances are often used this
way (as classes).
 
> John Maloney at Squeak central also has a great deal of experience
> with Self, and yet for various reasons is now working on Squeak.
> I'll let him speak for himself as to why this is.

Yet, I think Morphic in Squeak suffers somewhat unduly for not being in
a system with true prototypes and related tools. We end up with this
sort of mix of concepts, and it is confusing. Would it be less confusing
if classes were just prototypes? I don't know. In general, I think we
would need better tools for managing this complexity of many singletons
(e.g. a button instance with a specific method it calls when pressed)
where such tools operate on classes and singletons (and class instances)
identically -- basically merging browsing and inspecting.

I agree there are many valuable ideas in classes and using super. If I
did prototype work, I would probably effectively make classes one way or
another (rather than copy entire complete objects). My idea at this
point might be to have instances point to a method table (also an
instance), and if instances want to have different methods, they copy
this table and update it, and perhaps make a link from the new to an old
(useful for development tools and programming sanity, but otherwise not
required). But you speak for real experience. My prototype work is
limited mainly to NewtonScript.

At this point, I see the greatest value to the hierarchical nature of
Smalltalk classes as an efficient way to ensure that instance variables
have non-conflicting indexes in compiled methods. I'm not sure how to do
this other than by managing a hierarchy (or having dictionaries for
instance variables) -- although possibly more sophisticated algorithms
could be used (like for allocating CPU registers). But as you point out,
these lead to brittleness in other parts of the system.

-Paul Fernhout
Kurtz-Fernhout Software 
=========================================================
Developers of custom software and educational simulations
Creators of the Garden with Insight(TM) garden simulator
http://www.kurtz-fernhout.com





More information about the Squeak-dev mailing list