[squeak-dev] A Sad Day

Trygve Reenskaug trygver at ifi.uio.no
Fri Aug 14 09:01:28 UTC 2020


Hi Marcel,
I am 90, and decided I did not want to spend the rest of my days with a 
Squeak I had no hope of understanding. That was the reason behind my 
goodbye-message where I was endeavoring to be as concrete and 
non-emotional as I possibly could. I then put everything Squeak in cold 
storage and picked up my life with other activities. Unfortunately, you 
wrote:

      Class MyConnector>> processEvent: anEvent using:
    anIgnoredDispatcher is a regular event handler in 3.10.2. In 5.3, it
    is a filter, and its execution never stops.
    That's just not true.

I am deeply offended because you accuse me of lying. I reluctantly had 
to retrieve Squeak from its storage yesterday and spend most of the 
night awake trying to formulate a non-emotional answer. This is the result:

START FACTS
My Squeak Reverse Engineering program (SRE)  lets me build a diagram 
with nodes and connectors. I add new nodes interactively and the 
connectors are added automatically. The connectors behave as expected 
with the redbutton letting me add breakpoints to a connector line and 
the yellowbutton opens a menu as usual. SRE has been working for many 
years under Squeak 3.10.2 and has proven very useful.

I have copied and compiled the SRE classes into Squeak 5.3. I can still 
build a diagram with its nodes and connectors *BUT the image freezes 
immediately if the cursor touches a connector*. This anomaly is 
consistently reproducible and is a clear bug. I WAS NOT LYING!
END FACTS

I tried to debug the program. It was not easy because the normal 
debugging tools do not work in this case. My tentative findings were:

    1)
    The first error is a MNU: Your system believes my connector object
    is an event, which is isn't.

    2)
    /MyConnector>> processEvent:using:/ is called from
    /MorphicEventDispatcher/, differently in the two releases:
    3.10.2     MorphicEventDispatcher>>dispatchDefault: anEvent with: aMorph
    5.3          MorphicEventDispatcher>>dispatchEvent: anEvent
    toSubmorphsOf: aMorph

I have copied the 2 methods below. The suspicious message is in 5.3: 
/f//ilteredEvent := child //processEvent: localEvent //using: self. / 
This assignment to a filter seems to be the root of the problem.

    *3.10.2>>**MorphicEventDispatcher>>**dispatchDefault: anEvent with:
    aMorph*
         "Dispatch the given event. The event will be passed to the
    front-most visible submorph that contains the position wrt. to the
    event."
         | localEvt index child morphs inside |
         "See if we're fully outside aMorphs bounds"
         (aMorph fullBounds containsPoint: anEvent position)
    ifFalse:[^#rejected]. "outside"
         "Traverse children"
         index _ 1.
         morphs _ aMorph submorphs.
         inside _ false.
         [index <= morphs size] whileTrue:[
             child _ morphs at: index.
             localEvt _ anEvent transformedBy: (child transformedFrom:
    aMorph).
             (/*child processEvent: localEvt using: self)*/ == #rejected
    ifFalse:[
                 "Not rejected. The event was in some submorph of the
    receiver"
                 inside _ true.
                 localEvt wasHandled ifTrue:[anEvent copyHandlerState:
    localEvt].
                 index _ morphs size. "break"
             ].
             index _ index + 1.
         ].
         "Check for being inside the receiver"
         inside ifFalse:[inside _ aMorph containsPoint: anEvent position
    event: anEvent].
         inside ifTrue:[^aMorph handleEvent: anEvent].
         ^#rejected

and

    *5,3>>MorphicEventDispatcher>>dispatchEvent: anEvent toSubmorphsOf:
    aMorph*
         "Dispatch the given event to the submorphs of the given morph.
    For coordinate transformations, work only with copies. Either return
    the given event or a copy of any filtered event to employ
    immutability to some extent. --- PRIVATE!"
         | localEvent filteredEvent |
         aMorph submorphsDo: [:child |
    localEvent := anEvent transformedBy: (child transformedFrom: aMorph).
    /*filteredEvent :=*//*child *//*processEvent: localEvent *//*using:
    self. "use same dispatcher"*/
             filteredEvent == #rejected ifFalse: [ "some event or
    #rejected symbol"
                 self flag: #overlappingChildren. "mt: We cannot give
    two overlapping siblings the chance to handle the event!"
                 ^ self nextFromOriginal: anEvent local: localEvent
    filtered: filteredEvent]].
         ^ #rejected


The 5.3 version assigns the result of MyConnector>> processEvent:using: 
to a variable called /filteredEvent/. Nothing like that happens in 
3.10.2, yet you claim that /"The dispatcher is still dispatching as it 
was in Squeak 3.10.2"/. Since /MyConnector>> processEvent:using:/ has 
never returned an event, the program is doomed to fail.

To avoid any further problems, I repeat that I am reporting to the best 
of my ability what I have experienced with a real program running in 2 
real Squeak releases on real hardware. I also trust that the 2 methods i 
have quoted exist in the release images even though I have copied them 
from one of my debugging images.

I hope I can return everything Squeak back to its cold storage and that 
it will stay there.
Have fun and goodbye
--Trygve


On 2020-08-13 09:59, Marcel Taeumel wrote:
> Hi Trygve.
>
> > Class MorphicEventDispatcher has 4 methods in 3.10.2 and 16 methods 
> in 5.3.
>
> Finally, we managed to improve modularity of Squeak's event handling 
> by assembling -- once scattered -- methods and logic in a place where 
> it can be found and understood. Of course, the number of methods in a 
> class can go up in the process. What you describe as "additional 
> bloat" is clearly a revelation of already existing complexity.
>
> Since the plain number of methods is rather unhelpful to assess code 
> readability, I wonder whether there are better names we can use to 
> guide programmers when exploring MorphicEventDispatcher, its 
> protocols, and methods.
>
> > Class /MyMorph>> processEvent: anEvent using: anIgnoredDispatcher /is 
> a regular event handler in 3.10.2. In 5.3, it is a filter, and its 
> execution never stops.
>
> That's just not true. The dispatcher is still dispatching as it was in 
> Squeak 3.10.2. Event filters were added as a mechanism to tackle the 
> existing mis-use of event listeners. The filter mechanism uses 
> patterns that are already existing in the Squeak system. Yes, there is 
> still room for improvement regarding its modularity.
>
> ***
>
> We need better ways to assess the image quality. Phrases such as 
> "unbelievable image bloat", "many thousands of classes", etc. are not 
> helpful at all. Such a perspective ignores incidental vs. accidental 
> complexity. It also ignores the role of tools in such a live and 
> exploratory programming system.
>
> We need better ways to look beyond the source code. Of course, we 
> strive for a clean, compact, understandable system. However, that goal 
> must not only focus on lines of code, number of 
> methods/classes/packages. Programmers do not just read code to gather 
> understanding. They execute code, play around with objects ---> use 
> tools. Those tools show us the names and relationships of all kinds of 
> software artifacts. Those tools enable very concise, task-specific 
> views on rather complex systems. Those tools can help find redundancy, 
> clarify meaning.
>
> Don't get me wrong. I am always in favor of removing a class or 
> concept if that is not necessary. I do think twice before adding a new 
> class or extending the inheritance tree.
>
> However, just counting the number of code artifacts is not a helpful 
> metric to move forward. It can only be a first step in a more 
> throrough exploration process.
>
> Don't give up. Happy Squeaking! :-)
>
> Best,
> Marcel
>>
>> Am 13.08.2020 09:34:39 schrieb Trygve Reenskaug <trygver at ifi.uio.no>:
>>
>>
>> Dear All,
>> Imagine that you bought an iPhone 20 years ago. Over the years, you 
>> have filled it with pictures, contacts, and other personal data. You 
>> now want to upgrade to iPhone SE and find that all your personal data 
>> are lost because there is no way to transfer your data. Very sad.
>>
>> The same has happened to me with Squeak. The Squeak programs I have 
>> written over the past 20 years are effectively lost because I can’t 
>> port them to a current version of Squeak. Very sad.
>>
>> The essence of object orientation is that objects collaborate to 
>> achieve a goal. I retired 20 years ago and made it my task to create 
>> DCI (Data-Context-Interaction), a programming paradigm that merges 
>> the concepts of class and collaboration. BabyIDE is a non-intrusive 
>> Squeak program that includes a model of DCI as well as tools for 
>> programming within the paradigm. BabyIDE is a kind of Dynabook, a 
>> personal computer for experts in all domains. Its target group could 
>> be department managers in business and industry; they are experts in 
>> running their department in collaboration with other managers. 
>> Another target group could be farmers; they are experts in taking 
>> care of their animals. A third target group could be homeowners; they 
>> build expertise in controlling their smart home.
>>
>> Squeak is more than a programming language; it is a live universe of 
>> collaborating objects. The shared objects on the web is also a 
>> universe of collaborating objects that Kevin Kelly called a /single, 
>> global machine/. BabyIDE extends the Squeak image into this global 
>> machine, making all the combined objects available for personal 
>> programming as illustrated below:
>>
>>
>>
>> BabyIDE is now running in Squeak 3.10.2, together with a new Squeak 
>> Reverse Engineering tool. I want to port my programs to Squeak 3.5 to 
>> benefit from its improved internet communication facilities. This 
>> port has been pestering me since April, but the overwhelming 
>> complexity of 3.5 has forced me to accept defeat. I can’t avoid 
>> speculating about the nature of Squeak’s current target group. It 
>> used to be “children of all ages.” Today, it neither includes 
>> children nor old Smalltalk hands like me (I wrote my first Smalltalk 
>> program in 1978). Stephen Pope, another veteran who also bemoans what 
>> is happening to Squeak, wrote in a blog:
>>
>>     /“//The most popular systems (Squeak and Pharo) both suffer from
>>     unbelievable image bloat, with many thousands of classes,
>>     hundreds of root classes, class hierarchies with many instance
>>     variables in the high-level (abstract) classes, and too many
>>     packages with cute but meaningless (to a new-comer) names.”/
>>     https://smalltalk.tech.blog/2020/08/10/smalltalks-successor/
>>
>> I couldn’t agree more. A few examples:
>>
>>     1.Class Object defines 485 methods. This means that every Squeak
>>     object understands at least 485 messages. Most of them are
>>     irrelevant to the problem at hand, but all of them can be part of
>>     unexpected behavior.
>>
>>     2.The state of every Morph object is held in its regular instance
>>     variables PLUS any number of undeclared and undocumented
>>     variables in its /extension/, a Dictionary that may include
>>     another dictionary inside it. The Morph class comment:
>>     /“MorphExtension Allows extra properties to be stored without
>>     adding a storage burden to all morphs.”/ I’m more concerned about
>>     the burden put upon the code reader.
>>
>>     3.For me, the final straw was the new filtering phase added to
>>     Squeak’s already complex event handling mechanism. Squeak 3.5 has
>>     208 new methods with ‘filter’ in their name, but there is no
>>     indication as to what they are for and when to use them. The
>>     abstract concepts of event filtering are documented, but there is
>>     no documentation on their reification into concrete code. The
>>     complexity of a basically simple mechanism has reached a new high
>>     far beyond the capabilities of my brain.
>>
>>     4.Class MorphicEventDispatcher has 4 methods in 3.10.2 and 16
>>     methods in 5.3.
>>
>>     5.Class /MyMorph>> processEvent: anEvent using: anIgnoredDispatcher/
>>     is a regular event handler in 3.10.2. In 5.3, it is a filter, and
>>     its execution never stops.
>>
>>
>> After 60 years in programming, 42 of them in Smalltalk, and the last 
>> 20 in Squeak, I have reached the end of my patience and reluctantly 
>> have to quit Squeak programming. It is truly a sad day.
>>
>> Have fun and Goodbye,
>> --Trygve
>>
>> -- 
>>
>> /The essence of object orientation is that objects collaborateto 
>> achieve a goal. /
>> Trygve Reenskaug mailto: trygver at ifi.uio.no 
>> <mailto:%20trygver at ifi.uio.no>
>> Morgedalsvn. 5A http://folk.uio.no/trygver/
>> N-0378 Oslo http://fullOO.info
>> Norway                     Tel: (+47) 468 58 625
>>
>

-- 

/The essence of object orientation is that objects collaborateto achieve 
a goal. /
Trygve Reenskaug mailto: trygver at ifi.uio.no <mailto:%20trygver at ifi.uio.no>
Morgedalsvn. 5A http://folk.uio.no/trygver/
N-0378 Oslo http://fullOO.info
Norway                     Tel: (+47) 468 58 625

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20200814/b8ef60df/attachment.html>


More information about the Squeak-dev mailing list