[squeak-dev] The Pillars of Squeak

David Goehrig dave at nexttolast.com
Mon Jul 6 14:14:14 UTC 2009


On Mon, Jul 6, 2009 at 7:03 AM, Ralph Johnson <johnson at cs.uiuc.edu> wrote:

>  But I think that the forces opposing
> minimalism are probably complex and powerful.  If we don't understand
> them, we are unlikely to defeat them.


The force that opposes minimalism is actually just mental inertia.  It is
easier to not think about what you're doing, and fling code at a problem
until you find a solution.  To actually consider how the semantics of the
method and object names you choose will affect future developers is simply
beyond the capacity of most programmers, who tend to get hung up on the
details of implementation.  And when they do, the remainder of the
complexity that creeps into Squeak images is a product of "taste".

Look at how many methods are in core classes that there because of some
weird corner case where the semantics did not quite work.  Objects
veryDeepCopy* tend to fall into this category.  Then you get the pure
semantic sugar methods, which can be found in methods such as the
SyntaxMorph's polution of object with the 5 selfWrittenAs* methods.

Then there is the huge number of methods
that are in desperate need of some thought and refactoring.  Consider:
anObject actionMap

vs

EventManager actionMapFor: anObject

vs

EventManager actionMaps at: anObject ifAbsent: [ EventMangager createActionMap ]

And then consider what the Morph class does in comparison.

aMorph extension valueOfProperty: #actionMap.

vs

aMorph extension otherProperties at: aSymbol ifAbsent: [^ aBlock value]

where extension is
a MorphExtension object, and otherProperties is an IdentityDictionary.

If you look at what is actually trying to be done, both cases are attempting
to provide ad hoc properties to a base object.  On the one hand, a global
external weak reference dictionary was used to do the mapping, and on the
other a per-instance dictionary was created to amend the object's
properties.   They do the same thing (return a dictionary) with roughly the
same semantics, but this is definitely a simpler way than having two
hyperbolically parallel implementations.

What really needs to happen at some point is a "Grand-Refactoring" where in
some fundamental architectural changes can be made with a view towards
simplifying the end-user semantics.  Look at all the places someone has
hacked a new method in a core class, that is only used in a specific context
or work around, and then identify the features and generalized semantics
that would have accounted for what became a fringe case.   One feature that
would fix many of these issues is to just provide one standard way for
instances of Object to add ad hoc properties and methods.  Another feature
that has yet to be used properly is traits.  Packages are a third.

Why a Grand-Refactoring might never happen, is it will require rewriting
substantial amounts of the image, and will necessarily break all existing
applications.  You can leave in shims to port old code, but unless you
remove them quickly (within a year) you ensure that habitual factors will
prevent them from ever being removed. You can also do a
Slightly-Less-Grand-Refactoring every couple years, to pick any weeds that
have grown up between the cracks, or fix issues that people have been
working around in the original one.  But you don't want to pump out one of
those more than once a year, to give people a stable base.

Overcoming mental inertia is very hard work.  You have to change your
habits, and see things you've stared at for too long with fresh eyes.  But
it can be done if there is enough will in the community.

-- 
-=-=-=-=-=-=-=-=-=-=- http://blog.dloh.org/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20090706/36af70e2/attachment.htm


More information about the Squeak-dev mailing list