"Singletons" package on SM

Avi Bryant avi at beta4.com
Thu Dec 4 10:36:59 UTC 2003


On Dec 4, 2003, at 12:17 AM, ducasse wrote:

Stef, thanks for taking the time to respond.  It's late, so hopefully  
my ramblings below make sense:

>> This package adds the #becomeSingleton method to Object, which will  
>> transform the receiver into an instance of a new, anonymous subclass  
>> of its original class.
>
> why subclass of the original class. because now if you do
> 	inst class superclass you will get your normal class. This is quite  
> strange.

Why is that strange?  I don't see anything wrong with that - it's the  
exact semantics I wanted.

> You should have a look at my comparison  
> http://www.iam.unibe.ch/~scg/Archive/Papers/ 
> Duca99aMsgPassingControl.pdf
>
> If I remember well in VW I did something similar, but
> 	I created a new behavior copied the format of the class to this  
> behavior, then compile class to be superclass
> 	and superclass to be class superclass.

Ah, I may now understand your objection better - what you were doing in  
your paper was trying to affect an entire class of objects at once,  
transparently.    I'm trying to affect a single instance, and it  
doesn't need/want to be transparent.  I'm not using the existing lookup  
mechanism to hack in new semantics (like my Mixin implementation does,  
for example), I'm really just trying to introduce a new way of defining  
subclasses (that happen to have exactly one instance).

> Anyway have a look this was fun.
>
> What I would say is that these kinds of hack are fun but after to make  
> them working in an integrated way
> you have much more problems.

Again, for my goal (anonymous, instance-based subclasses), I don't  
think any further integration is really needed (well, it might be nice  
to show the singleton methods in the Inspector, but that's really  
minor).  It's not a hack in that sense - I would have no qualms using  
this in production code (I think - maybe someone can convince me  
otherwise).  I think the main integration problems would come if you  
were introducing new CompiledMethods with source code into these  
subclasses, but since I'm using MessageSends and blocks (through  
Andreas' ObjectsAsMethods stuff, but could also be MethodWrappers),  
there are no ugly calls to #compile: or anything.

>> My expectation is that this might be useful as a replacement for  
>> specifying pluggable behavior with block inst vars or target/selector  
>> pairs, particularly for UI classes.
>
> Why is it really a problem?

Two things.  One is the idea of "unplanned reuse", which I think  
Smalltalk generally excels at: if you have well factored code, it's  
often very easy for someone to come along later and introduce a  
subclass where you had no idea that someone would want to change the  
behavior you started with, simply by redefining a few key methods.   
However, this kind of reuse is only possible through subclassing - to  
reuse code through composition, the developer has to have left you  
explicit "pluggable" hooks.  Since I think composition is often a  
better solution than subclassing in other ways, I think this is a  
shame.  This puts subclassing and composition on equal grounds in that  
respect.

Second, it's very common for someone to build in extensibility in two  
ways (subclassing and composition) by having an abstract class that  
defines a #subclassResponsibility, have some concrete classes that  
fulfill this responsibility, and then have a Pluggable subclass that  
allows the user to supply a block to fulfill the responsibility  
instead.  An example close to this is Set, IdentitySet, and  
PluggableSet.  With this delegation code, someone just has to mark the  
extensibility points once with #subclassResponsibility, and that same  
responsibility can either be fulfilled by an explicit subclass, or by  
an anonymous instance-based subclass (ie, through composition), with no  
need for the boilerplate of a "Pluggable" version.  And note that, like  
Traits, this approach may remove the need for copied code in  
IdentitySet and IdentityDictionary - instead, you would have a separate  
IdentityScanner class that implemented the revised #scanFor:, and to  
make a Set *or* Dictionary into an Identity[Set|Dictionary], you could  
say

collection delegate: #scanFor: to: (IdentityScanner for: collection).

Or something along those lines.  Hmm... to achieve this otherwise you  
would need the hierarchy

Set
   PluggableSet
      Dictionary

which is ugly for all kinds of reasons (including performance ones).   
So even if you *are* planning for this kind of reuse, the block  
pluggability still looks like it's worse.  (Ok, having realized that, I  
ought to rewrite this argument to be based entirely around that  
example, but it really is late so I'll let the rambling stand).

Cheers,
Avi




More information about the Squeak-dev mailing list