Radical suggestions

rob van den berg rvdberg at best.ms.philips.com
Fri Jul 16 07:29:12 UTC 1999


Hi,

Ok, I have to first say that I haven't coded in Smalltalk enough, more so never ever
worked with Visual SmallTalk, to have been needing changes to core classes. My
background in medical and Space domain also makes that I want to have
(sub)systems/packages whose behaviour is always predicatable. Let me try to rephrase
my concerns a bit clearer:

The reason one divides a system into packages is for reasons of clarity and control.
Good packages have loose coupling and high cohesion. Splitting a class into multiple
packages is not a problem, However these packages should then only included methods
from one class(i.e. the current categories). In this case there should be a
hierarchical structure which closely ties the categories together so that the class
will still be one unbreakable (composite) package. Off-course as with any principle,
there are always situations where this position is not tenable. But we should not
make it easy for people to do this and potentially break systems (voices from the
FDA can be heard in the background). Finally if classes are properly defined they
should be general enough

BTW: Relaying on tools to solve unwanted behaviour is a dangerous approach: if used
improperly, they allow you to produce more garbage than without them, as they lull
you in the believe that they will do the work.

Finally, I do like the idea of packages, I can also live with packages containing
parts of a class. But it should not be possible to use only parts of a class: as I
said before classes /objects should behave like atomic entities.

To rephrase an old Roman: and still I am of the opinion is that we should use
subclassing instead.

regards,

rob

Christian Brunschen wrote:

> On Thu, 15 Jul 1999, rob van den berg wrote:
>
> > Christian,
> >
> > I like the suggestion of using packages. Dan's concise and clear comments on
> > the 'Working Together' discussion also point into that direction. However, I
> > don't think that it is such a good idea to be able to give methods a 'package
> > scope": a class/object should be an atomic entity; everything belonging to a
> > class/object should be defined in the same place. You cannot just rip out
> > parts of an object! Apart from the philosophical implications, it would not
> > like to do maintain software written in that way!
> >
> > Also I am wondering what the great gain would be: either you are not happy
> > with a core class, i.e. Dictionary: in which case you should try to convince
> > Squeak Central, or you want a specialised Dictionary, in which case you should
> > subclass Dictionary.
> >
> > Maybe you can clarify this?
>
> I didn't mean to imply that method definitions should be placed anywhere
> other than they are now (unless the developer chose to - more on that
> later).
>
> Let me try to explain it a bit better.
>
> I'll use Java syntax and semantics for a while here, because those are
> well-defined in respect to packages:
>
> ----
> package com.brunschen.foo;      // yes, brunschen.com is _my_ domain. :)
> import java.io.*;
> import java.util.*;
>
> public class Foo extends Object {
>         Reader reader;
>         Hashtable hashtable;
>         Foo () {
>         }
> }
> ----
>
> In the example, I first declare that this file is part of package
> 'com.brunschen.foo' - 'com.brunschen' is the reverse of my internet domain
> and thus guaranteed to be globally unique; 'foo' is a sub-package name
> that I have chosen arbitrarily.
>
> I then import all things declared in the 'java.io' package.
> Likewise, I import everything in 'java.util'.
>
> Importing basically makes the symbols in question available to the code
> not just by their fully-qualified name, but also by their unqualified
> name (more on this later, when I can show an example).
>
> I define class 'Foo' to extend 'Object'. 'Object' is not something
> that is defined in the current code; however, _all_ java code
> automatically imports everything in the 'java.lang' package, so when
> searching through all the imported symbols, the compiler finds sonething
> that has a non-qualified name of 'Object' - 'java.lang.Object'.
>
> Likewise, 'Reader' is searched for and found to be 'java.io.Reader', and
> Hashtable is 'java.util.Hashtable'. So, in effect, the code could be
> written as
>
> ----
> package com.brunschen.foo;
>
> public class Foo extends java.lang.Object {
>         java.io.Reader reader;
>         java.util.Hashtable hashtable;
>         Foo () {
>         }
> }
> ----
>
> Here, all imports have been removed, and package affinity has been made
> explicit.
>
> What I am proposing is that, in effect, not only _class_ names get
> prefixed with the package they are defined in, but also _method_ names
> would get the same treatment.
>
> This would mean that if I defined something like
>
> package com.brunschen.foo
>         class Foo               // full name: com.brunschen.foo.Foo
>                 method bar      // full name: com.brunschen.foo.bar
>
> package org.hacker.foo
>         class Foo extends com.brunschen.foo.Foo
>                                 // full name: com.someone.foo.Foo
>                 method bar      // gets resolved to
>                                 // com.brunschen.foo.bar
>                 method org.hacker.foo.bar
>                                 // full name explicitly given
>
> This would mean that the 'com.someone.foo.Foo' class could behave
> differently depending on wether it was called from a context which had
> imported only 'com.brunschen.foo' versus one which had imported
> 'org.hacker.foo'; ie, depending on wether it was being called as 'a
> subclass of brunschen.com.foo.Foo' or as 'an org.hacker.foo.Foo'.
>
> Also, consider if I want to write a class that is to be used by other
> objects from two different developers. Each of these other classes expects
> my object to implement the method 'foo', but each has its own distinct
> idea of the semantics of 'foo', even though the syntax is the same.
>
> Say that I want to write a class to implement a character in an
> animation, who is a gunfighter. The animation package places each object
> to be animated in some sort of display list, and when the time comes to
> create an image of the current scene, each object is sent the 'draw'
> method.
> Likewise, the 'OK Corral' simulation software will, at some time or other,
> send my object the 'draw' message to instruct him to draw his gun.
>
> Now, I can not change either of these calls; they will occur. And I really
> don't want to have to write a 'wrapper' class to hand to receive one of
> the 'draw' calls. Now, if each 'draw' method were to the corresponding
> 'package.draw' method - 'OKCorrar.draw' and 'Animator.draw' respectively -
> I would just implement each of those, and things would work magically.
>
> And anyone who used my class later, in a context where they had imported
> the 'Animator' package, would automatically access the 'Animator.draw'
> method, whereas anyone writing from the point of view of the OK Corral
> simulation would get 'OKCorral.draw'.

Christian,

If Animator was properly defined you should be able to subclass the method draw.
e.g.

Animator subclass: #OKCorral

draw
    super draw.
   ....
   ^self

I am correct in the assumption that you are trying to do something

>
>
> Any conflicts or ambiguities would be flagged at compile-time.
>
> All the core classes, and their methods, could be defined in
> 'Smalltalk.core'.
>
> But if someone wrote an 'alternate' set of 'core classes', they might end
> up with similar method names, but with perhaps different semantics in some
> cases even though the selector was the same.
>
> With package-qualified method names, I could write my own classes to
> work appropriately with _both_ sets of 'core classes'; or for that matter,
> I could develop the new core classes alongside with running the old ones,
> slowly migrating the whole system over, which still maintaining
> functionality of those parts that has not been moved to the new core
> classes.
>
> By the way, defining everything in the same place is not always necesarily
> the best thing there is.
>
> What if I find a bug in a class that it is none of my business to fiddle
> with? Or if the developer of said class simply refuses to fix the bug?
>
> If you take a look at the Objective-C language as used in OPENSTEP, you
> will find that it includes something called 'Categories', which allow
> methods for the same class to be defined in different files. In fact,
> an Objective-C Category can be loaded and added to a class at runtime.
> This is especially useful for the specific case when an existing class
> must be used, where that same class is in some way buggy or insufficient,
> but where adding new methods, or overriding existing ones, could fix the
> problem.
>
> The same solution (ie, allowing method definitions for a class to be
> spread out over several places, as wel as generally allowing
> additions/changes to existing classes) is used in the Tom language
> <http://gerbil.org/tom/> by Pieter J. Schoenmakers - see
> <http://gerbil.org/tom/highlights/fastex1.shtml> .
>
> > One thing is clear: using modules/packages will complicate things: it is more
> > effort to create stable installation releases: every extra file needed
> > introduces an extra problem source. We need some sort of core class/object,
> > able to validate the state of the current Squeak install.
>
> I beleive that separation of things into packages, _if done right_, helps
> maintainability of each package and of the system as a whole.
>
> >
> > regards,
> >
> > rob
>
> No comments on my second suggestion - that of a Squeak-internal 'Object
> System' ?

No objections

>
>
> Best regards,
>
> // Christian Brunschen

--
-_-__----__----___-----____---__-_-_-_____--___--
rob van den berg rvdberg at best.ms.philips.com
+31 40 27 62787  Philips Medical Systems, Netherlands





More information about the Squeak-dev mailing list