[squeak-dev] Re: [ANN] Unload Traits script
Andreas Raab
andreas.raab at gmx.de
Mon May 12 12:41:03 UTC 2008
Hi Matthew -
This is very interesting work. Your script presents a unique opportunity
to actually compare the traitified version of the class kernel with one
that doesn't have these modifications applied and compare notes
directly. I am still in the process of doing that, but one thing that I
almost instantly noticed was the subjective feeling that "sanity had
suddenly returned" to a previously insanely complex part of the system.
And I'm slowly starting to understand why that is.
Let's do a little exercise: One thing I regularly do when there are
changes to the class kernel is to go through the main hook for method
addition (addSelector:withMethod:) to see if there are any changes along
the way. When you do this in the image without traits you end up with an
exploration chain like here:
* addSelector:withMethod: has one implementor which calls
addSelector:withMethod:notifying:
* addSelector:withMethod:notifying: has two implementors (in Behavior as
well as ClassDescription) where the latter is basically just adding the
SystemChangeNotifier around its superclass implementation. Both versions
call addSelectorSilently:withMethod:
* addSelectorSilently:withMethod: has the same pattern (the base
implementation in Behavior and an added notification in
ClassDescription) which calls methodDictAddSelectorSilently:withMethod:
* methodDictAddSelectorSilently:withMethod: calls then
#basicAddSelector:withMethod: which ultimately does the work.
Coincidentally, the last two methods are completely superfluous and
could just be folded into Behavior>>addSelectorSilently:withMethod:
(which is the implementation in 3.8).
The total number of entities to deal with in this case is seven methods
(five if you discount the last two) in two classes.
Now let's do the same for the traits version:
* addSelector:withMethod: starts out with showing four implementors; two
traits (TCompilingBehavior and TPureBehavior) as well as two classes,
TraitBehavior and Behavior. The implementations look identical but it is
not clear if they are and how one would actually find out.
* addSelector:withMethod:notifying: shows *seven* implementors; but with
only two obviously different versions which are the ones ultimately used
by Behavior and ClassDescription
* addSelectorSilently:withMethod: shows again seven implementor; this
time with four apparently different implementations
* methodDictAddSelectorSilently:withMethod: shows three implementors
with only one apparent implementation of the method
* and finally, basicAddSelector:withMethod: shows another four
implementors with only one apparent version of the method.
Total number of entities dealt with in the process: 25 methods, 4
classes, 3 traits. Even if you ignore those parts that aren't present in
the first image, you still end up with 18 methods, 2 classes, 3 traits.
In other words, the relative complexity one needs to deal with to
perform the same task is about 3-5 times higher.
I think that's the main problem that I have with the implementation at
hand. Any measure that I can think of to compare complexity comes up
with at least a doubling of the complexity introduced in the class
kernel, many of them show *much* larger increases. This is very similar
to the issues observed here:
http://lists.squeakfoundation.org/pipermail/squeak-dev/2007-August/119295.html
where the amount of complexity explodes similarly. I'm not completely
sure at this point whether the issues should be attributed to lack of
tool support, or whether they are just the natural result of using MI
inappropriately. I currently tend towards the latter because even with
better tools significant amounts of extra complexity would remain and
there is no real justification for the use of MI in that part of the system.
In any case, this is truly a *great* opportunity for people who haven't
made up their mind to compare both versions directly and see which one
they prefer.
Cheers,
- Andreas
Matthew Fulmer wrote:
> I wrote a script that removes traits from a 3.9 or 3.8 image:
> http://installer.pbwiki.org/UnloadTraits
>
> In an image with Installer (preferably LPF), do:
> Installer install: 'UnloadTraits'
>
> I tested this in 3.10, 3.9, and 3.9.1
>
> What it does:
> - Stop all trait activity
> - Recompile all classes into the old format
> - Remove all traits from the system
> - Get rid of pointers to traits or traits-related classes
> - Remove/modify lots of methods that understand traits
> functionality
> - Unload the traits package
> - Install 3 stub methods so that Monticello versions descended
> from 3.9 still work
>
> This is not a modular solution, but it does make a 3.10 or 3.9
> system with no traits around anywhere, and the resulting image
> is quite stable. I don't intend to make Traits loadable right
> now, but if you want to, I can answer questions.
>
> Have fun
>
More information about the Squeak-dev
mailing list
|