[Q] Fiddling with system innards, was [Q] Newbie - Multiple Return Values

John W. Sarkela sarkela at sbcglobal.net
Thu May 1 18:00:28 UTC 2003


Hello Ingo,

Welcome to the world of Smalltalk. I ask you to prepare yourself to 
turn all of your ideas about the "proper order" of things inside out. 
Much of the wisdom of your experience will apply in this world, much 
will not. Your task is to draw that distinction effectively.

The first observation is that the world of Smalltalk consists of two 
basic elements,
	1. The imperative, the message send
	2. The structure, the class

There are no other elements inherent in the world of Smalltalk, not 
even control structures.

So, don't be afraid to create classes to model the structure of intent. 
Classes are inexpensive and the *only* way to express structure in the 
environment. So use classes to define the structure and order of your 
system. There is no other option in Smalltalk.

With regard to Exceptions, it is quite appropriate to use exceptions as 
a means of signaling failure. As a designer, I wish to make the network 
architecture transparent with respect to the logical architecture of 
the system as a whole.

Thus
1. Assume all sends succeed. If a call returns it was successful. If 
not I am certainly in a state that I would hope to be truly exceptional.
2. At network boundaries wrap a handler that handles out of band 
occurrences. This would include not only link problems, but also 
asynchronous signals from the other endpoint. I have in the past put 
these behaviors in the proxies that abstract the network link from the 
object model.

One of my rules of thumb is that if my logical architecture (domain 
model) has knowledge of and dependency upon my technical architecture 
(platforms and channels) then I am not done designing.

On Thursday, May 1, 2003, at 09:53 AM, Ingo Hohmann wrote:

> Hi Cees,
>
> Cees de Groot wrote:
> <..>
>> Really, encapsulating the result in a class is much nicer, especially
>> because you can then start converting 'tell' methods into 'ask' 
>> methods
>> (don't "give me foo" but "please do bar with whatever you represent").
>> There's about zero overhead (probably exactly zero - whether you
>> construct an Array instance with two or three members or a FooResult
>> instance with two or three instance vars does not matter).
> <..>
>
> I'm quite willing to sacrifice some performance for clarity (otherwise 
> I'd be using assembler, or even -uuuugh- C), but

If instances of your result class are sufficiently explicit, not only 
will code clarity increase, but most likely the code will be more 
efficient. This is because a FooResult never needs to perform 
conditional tests at runtime to know what kind of thing it is.

A consequence of pushing discrimination to design time (ie the design 
of the structure of classes) is that at runtime there is no need for 
conditional testing to determine course of action. Paradoxically, his 
very often result in code speed ups.

As a side note, the following artifacts are all signs of missing 
classes,
	Arrays used as temporary structures.
	Methods with lots of arguments
	Lots of conditional tests
	Inquiry as to the class of a receiver

> where I come from fiddling with the system innards is supposed to be a 
> 'black art'.
>

Usually motivated by runtime environments that are not robust and that 
are inflexible, not because it is inherently black or to be avoided.

> Actually, my problem is that, everything I do is in the image to stay 
> - that's quite a difference to writing a script that changes whatever 
> it wants to in the system, when it does not interfere in any way with 
> other scripts/programs.
>
> _That's_ why I am reluctant to create new classes.

If your classes reflect a truly distinct intent and are manifest in new 
vocabulary, there will be no negative interaction. My experience has 
demonstrated time and again it is more likely that you will experience 
the surprise of your new definitions working in meaningful ways you had 
not considered.

>
> On a related note, assume I would like to do something with 
> strings/any standard class, that the current implementation does not 
> allow. What is the way to go then?
>
> Should I extend the String class in the system?
> Create a subclass of String that understands my additional messages?
> Create a StringHelper which understands #myMessage: aString?
>
> The latter seems to be the cleanest to me, what do you think?

If you have distinguished a new vocabulary that applies to Strings, 
then by all means extend the class String. Anything else is a dilution 
of intent. In a more rigid system, one would be taught a pattern of 
encapsulation (such as StringHelper) or subclassing in order to 
overcome the limitations of the runtime.

In summary,

	Model distinctions with classes.
	If something needs to be done, send a message.
	When sending a message, consider
		to whom (what classes of objects) should the message be sent?
		is the intent of the message explicit in the method selector?
	If a method has conditional behavior, ask yourself
		does this test reflect a distinction that is not modeled by class 
structure?
	If a method has lots of arguments or your are returning arrays, ask 
yourself
		are these arguments (or array) suggesting a new class of object?

>
>
> Kind regards,
>
> Ingo
>

The most important lesson of all is to dare to have fun. Experiment and 
learn, these are the driving principles hiding in Smalltalk.

Cheers,
:-}> John



More information about the Squeak-dev mailing list