About KCP and automatic initialize

Richard A. O'Keefe ok at cs.otago.ac.nz
Thu Sep 18 00:38:39 UTC 2003


Daniel Vainsencher <danielv at netvision.net.il> wrote:
	Just thought I'd note that Andreas suggestion is quite likely to break
	the RBParser in two ways - at the syntax level (+ isn't a legal first
	character in a selector), 

um, + *is* a legal first character in a selector.
In fact, just this mornign I realised that that's what's wrong with it.
    + new
under current syntax means "here is a method for #+ with argument 'new'".
oCasting around for an alternative,
    ^ <method header> <body>
adding
    <method header> ^self basicNew <method header>
to the class side should work.

Yes, the RB would have to be changed to know about this, just as the
system compiler would.

	Also, it is a language change that fixes initialization, but is very
	inconsistent with many  other things about Smalltalk.

Would you care to elaborate?

	But Smalltalk tools also assume that a method source they can
	read is a method source they can change and recompile.

Would ensuring that the relevant tools *don't* believe they can
read derived methods at least partly solve this?  We want the derived
methods to have certain *code*, but the point of derived methods is that
they are methods that people get without having to look at them.
With the derived methods that have been mentioned so far, no bug can
actually arise in a derived method, so even if the debugger just
displays reconstructed source code and refuses to change it, that
should be OK?

	I think the core issue here is that derived methods and
	Smalltalk don't really fit.
	
	Lets talk about alternatives -
	1. Avi proposed method annotations as a general syntax that would allow,
	among things the implementation of derived methods along these lines.
	These have the benefit of compatibility with VW, at least. Also they are
	powerful enough to solve problems other than initialization, so we won't
	be talking about another change quite as soon.

Nothing against method annotation.  Good idea.  But a derived method is
a derived method.  How is deriving a method via an annotation any friendlier
to existing tools than deriving a method via the compiler?  And if the
annotation is any heavier than "<new>", is it going to be as good for
beginners as Andreas Raab's suggestion?

	2. IIRC, Alan Kay once mentioned that he didn't particularly like the
	Metaclass solution to the initialization problem. I agree, and if that's
	really all that metaclasses are really needed for, I think we should
	seriously consider alternatives that are simpler. We might end up
	breaking compatibility on a wider scale, but at least we have a chance
	to end up with something that's simpler on the whole.
	
Personally, I *like* putting instance creation methods on the class side.
My mental model gets a bit more complicated in one way (for every class
there is a metaclass) but it gets a lot simpler in other ways (_everything_
is an object, _every_ action is the result of sending some message to some
object) and makes design patterns like Singleton, Flyweight, Factory, &c
so simple to implement that until I read the GoF book I never realised that
anyone might find them hard enough to do that they needed names.  The fact
that an instance creation method doesn't _have_ to return an instance of
its own class if it doesn't want to is quite powerful.

If a class has class variables, they may need initialising,
and there may be access methods for them.  A class may provide
constants, like TextColor does.  So that's two responsibilities:
    "create instances"
    "know stuff useful to all instances"
As far as I can see, all the externally useful methods for MIDIFileReader
are on the class side.

There are several ThingyReader classes in Squeak where you mainly
call them to do something rather than make an instance and ask it
to do something.  Sometimes that makes me a bit uneasy.  But on the
other hand, creating an object you have no real interest in bothers
me too.

Perhaps instead of
    aScore := MIDIFileReader scoreFromFileNamed: foobar.
we should use
    aScore := MIDIScore fromFileNamed: foobar
and instead of
    MIDIFileReader playFileNamed: foobar
we should use
    (MIDIScore fromFileNamed: foobar) play

But then 
    MIDIScore class>>
    fromFileNamed: aFileName
	^(MIDIFileReader onFileNamed: aFileName) asScore
is an instance creation method that doesn't act at all like a constructor.



More information about the Squeak-dev mailing list