new vs. initialize

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

new vs. initialize

Greg A. Woods; Planix, Inc.
So this problem I posted on squeak-dev about BDFFontReader and how it  
has its own #new class method to create new instances of itself, but  
in doing so failed to also send an #initialize message to each new  
instance and thus when it was actually used an instance variable was  
left as nil when it should not have been.

One recommendation was to simply remove the #new method and thus  
default to the superclass #new which, if I'm not mistaken, would then  
result in #new from Behaviour to be invoked and that one does also  
send #initialize to self.

I think, IIUC, this recommendation only makes sense because  
BDFFontReader is a direct subclass of Object.

Initially though this recommendation didn't make any sense to me  
because I didn't know how the implementation of #new in Behaviour is  
different from strict Smalltalk-80 as I understand it.  I.e.  
originally in Smalltalk-80 #new did not also send #initialize, but now  
in Squeak it does.

Just for fun I did a search for senders of #basicNew and I found quite  
a few which are from #new methods in classes which subclass directly  
from Object and which are in classes that also define their own  
#initialize method.  The curious bit is how some of these #new methods  
do send #initialize, but not all.  I'm guessing some that don't are  
for abstract classes, but is it true that all are?

Now I read on the WWW that the added sending of #initialize from  
Behaviour>>new was added in 3.9.

Unfortunately whomever actually did the change failed to document the  
important differences here, and why!  How is it that with such a  
wonderful system for documenting code we still end up with totally  
missing documentation?  I've now gone on a huge wild goose chase  
because of this.  How many others who have not kept track of how  
Squeak is evolving away from other Smalltalk-80 implementations will  
waste similar amounts of time?

I'm guessing that some of the now unnecessary #new methods are simply  
still not cleaned up since then?  If so, why not?  They're easy enough  
to find!

Also, doesn't this still create an _enormous_ portability problem with  
other Smalltalks?

(BTW, I'm not even sure I buy into any of the other arguments for  
having default invocation of #initialize, i.e. those beyond the  
blatant incompatibility with what seems to be _all_ other  
implementations and _all_ existing documentation about the  
fundamentals of Smalltalk.  I remember naively thinking this would be  
a good idea way back in the early 80's when I last spent any amount of  
time fiddling with Smalltalk, and I also seem to remember all the wise  
gurus around me quietly patting me on the head and telling me that no,  
such a change would not be welcome, and I should just learn to do  
things explicitly like they should be done.)

--
                                        Greg A. Woods; Planix, Inc.
                                        <[hidden email]>


_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners

PGP.sig (193 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: new vs. initialize

Tim Johnson

On Dec 8, 2008, at 8:56 PM, Greg A. Woods; Planix, Inc. wrote:

> Initially though this recommendation didn't make any sense to me  
> because I didn't know how the implementation of #new in Behaviour is  
> different from strict Smalltalk-80 as I understand it.  I.e.  
> originally in Smalltalk-80 #new did not also send #initialize, but  
> now in Squeak it does.

This recent (!) change to auto-initialize puzzles me as well.  So much  
existing code was written with the opposite case being true, that it  
seems so risky to change!  To diverge from the ST-80 standard is even  
more risky, I would think.

I was convinced that this change is the one-and-only reason why  
BDFFontReader became broken.  So what else is broken now because of  
this change?  I don't know.  What human logic instigated the change?  
I also don't know.  Perhaps it makes the system more accessible or  
consistent for newbies?

It was because of changes like this that I kind of threw in the hat on  
Squeak for a while, after 3.8 and before 3.10.  It seemed all these  
weird changes that  seemed illogical to me (a relative newcomer to  
Smalltalk) were being made, while existing problems were not being  
addressed.

- TimJ

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Re: new vs. initialize

Greg A. Woods; Planix, Inc.

On 9-Dec-2008, at 11:26 AM, Tim Johnson wrote:

>
> On Dec 8, 2008, at 8:56 PM, Greg A. Woods; Planix, Inc. wrote:
>
>> Initially though this recommendation didn't make any sense to me  
>> because I didn't know how the implementation of #new in Behaviour  
>> is different from strict Smalltalk-80 as I understand it.  I.e.  
>> originally in Smalltalk-80 #new did not also send #initialize, but  
>> now in Squeak it does.
>
> This recent (!) change to auto-initialize puzzles me as well.  So  
> much existing code was written with the opposite case being true,  
> that it seems so risky to change!  To diverge from the ST-80  
> standard is even more risky, I would think.
Well what really angers me about this change is that it's not properly  
documented in any way shape or form.  There's just the code, and even  
with all the code browsing tools in Squeak it still took me far longer  
than it should have to figure this out.  Part of that was my  
unfamiliarity with Behaviour and ProtoObject, but most of it was the  
total and complete lack of documentation about this difference.  Even  
outside the image itself there's just one very out-of-date page on the  
swiki about this, and it gives no details or proper rationalization  
whatsoever, and indeed it gives caution to some of the issues.  It  
certainly doesn't say it's a done deal -- in fact it's still in the  
"improving" section.  There's a very long and convoluted thread in the  
mailing list archives but as yet I haven't even read anywhere of any  
true consensus being reached (though many folks just seem to have been  
beaten into submission).

I am annoyed that anyone would want to change this fundamental little  
part of the basic Object protocol too.  #new is supposed to answer a  
new instance of the receiver.  Period.  Not also do any callbacks back  
to any other instance methods.  None.  RTFM.  Maintaining the status  
quo is very important when you're talking about fundamental parts of  
the object protocol.  Now Squeak documents Behaviour>>new as returning  
a new _initialized_ instance, but that's not (universally) true so  
it's very confusing.

Now every book, every paper, every web page, including tons of  
"squeak.org" web pages, are now (still) incompatible with the current  
(and previous) release of Squeak.  Squeak is now incompatible with its  
own earlier versions.  Squeak is now incompatible with code that used  
to work in Squeak, and at least one of the classes right in the main  
release, one which is used by a package still in the default package  
universes, has been broken by a naive change (a relatively long time  
ago) by someone who presumably should have known better (i.e. who was  
probably aware of the change to #new) and who obviously didn't test  
their change.

It seems to me that Squeak users _must_ now be experienced developers  
in order to be able to file in old code and actually make it work in  
far too many cases.  I.e. this change is a total failure when it comes  
to supporting _users_.  If I had given out code that somehow relied on  
the old #new protocol and then disappeared now only someone with  
enough experience and knowledge can make use of it in a new Squeak  
release.  Indeed this happens all the time in the world of software,  
all too often.  But that doesn't mean it should happen.  I'm beginning  
to understand why many serious Smalltalk programmers I've met in  
recent years consider Squeak to be no more than a toy.

I'm also beginning to understand why the gurus around me more than 20  
years ago were telling me that default initialization was a "Bad  
Thing(tm)".  First off, not everything needs to be initialized.  Also,  
as was discussed in some detail before, this most basic form of  
parameter-less initialization doesn't work for probably the majority  
of classes which really do need initialization upon instantiation so  
what exactly is the benefit anyway?  Even the Blue book effectively  
gives caution to why auto-initialization can be very tricky and far  
less helpful than it may at first appear to be (p. 274).

Finally I think that some of the apparent justification for this  
change, a topic that was bandied about on the mailing list way back  
when, is also naive in and of itself.  I'm referring to the claim that  
this change will help educators avoid having to deal with the meta-
level of how classes are implemented.  Don't get me wrong though --  
I've never taught Smalltalk, this is just from my experience of  
(trying to) learning it.  First off I think the problem with the  
concept of metaclasses in Smalltalk is that they're not exposed  
clearly and plainly enough in the first place.  The chapter(s)  
describing them in sufficient detail comes far too late in all the  
textbooks (especially the original one -- #16!?!?!?!).  The default  
code browsers have never been easily shown metaclass information in  
any decent way that properly lays out the structure and hierarchy of  
metaclasses and their protocols.  There's always been this attempt to  
smush metaclass and class stuff together so much that metaclasses are  
effectively invisible and that's always confused me.  Secondly,  
although I recognize there are limitations and constraints on teaching  
this stuff, I don't buy the argument that it's good to avoid talking  
about the meta stuff to students, especially not if it's just so that  
you can spend more time on "other things".  Not knowing that I should  
read ch#16 in the Blue book right away as soon as I needed to learn  
about the meta level left me confused and knowing that I was missing  
something fundamental for a very long time.  Maybe the "class" button  
in the browser should actually be a "metaclass" button as a reminder?

I don't really buy the "fragile instance" argument either.  Especially  
not for this most mundane change to just the two forms of #new and  
#new:.  There's just _way_ too much variation in existing practice of  
how to take a blank instance of an object into a well formed (ready to  
use) instance.  And there _should_ be!

I don't know if this change to add #initialize to #new is a big deal  
fundamentally or not -- I'm just blowing off steam.  My fundamental  
problem is that none of this was properly documented in the image  
despite the fact that Smalltalk includes excellent built-in  
documentation capabilities.  In reply to my problems with  
BDFFontReader I read something that seemed contrary to my fundamental  
20-year old understanding of Smalltalk-80.  I tried looking for  
answers.  I re-read books.  I re-read web pages.  I searched the WWW  
(it didn't help that the logical keywords here are very common) and  
most of my own printed material (books, papers, guides, etc.).  I  
grovelled around in the image for far longer than I probably needed to  
(I'm not yet familiar enough with all the available tools).  Nothing I  
read said anything about the magic of a #initialize method being part  
of the core Object protocol.  Finally I found where #initialize is  
sent from Behaviour>>new and where the default method is.  This  
contradicted _everything_ I read _everywhere_ about object creation  
and instantiation and initialization in Smalltalk-80.  Nowhere did any  
documentation in Squeak or about Squeak lead the way for me to  
understand this difference in Squeak's fundamental Object protocol, or  
give any explanation or rationale for this difference in Squeak.  
Sadly the changes in the image were compacted so I couldn't even see  
that this fundamental old protocol had been changed.

Shame on anyone who writes any class or method that ends up in the  
core image without proper detailed documentation!  Double shame on  
anyone who makes any change to any core protocol without documenting  
its purpose and rationale!  Document first, code later.  Those  
responsible for making changes to core protocols are, IMNSHO, also  
responsible for at least making sure outside documentation is also  
updated to reflect the new reality, if not actually doing the updates  
themselves.  You have a responsibility to the community, your peers  
and colleagues, and indeed all those interested stake-holders outside  
the immediate community too!

--
                                        Greg A. Woods; Planix, Inc.
                                        <[hidden email]>


_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners

PGP.sig (193 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: new vs. initialize

Zulq Alam-2
In reply to this post by Greg A. Woods; Planix, Inc.
Hi Greg,

My comments are below...

Greg A. Woods; Planix, Inc. wrote:

 > Now I read on the WWW that the added sending of #initialize from
 > Behaviour>>new was added in 3.9.

Where did you read this? I've been using Squeak for a few years and as
far as I know the default implementation of #new has always sent
#initialize.

The history of Behaviour>>new shows one version dated 23-8-2003. This is
well before 3.9.

> Just for fun I did a search for senders of #basicNew and I found quite a
> few which are from #new methods in classes which subclass directly from
> Object and which are in classes that also define their own #initialize
> method.  The curious bit is how some of these #new methods do send
> #initialize, but not all.  I'm guessing some that don't are for abstract
> classes, but is it true that all are?

There are a number of reasons one might call #basicNew, e.g.
compatibility with other dialects, limiting use of #new by signalling an
error, avoiding the normal initialisation from an alternative
constructor, etc. In most cases "super new" would also work.

Those that call intitialize may do so because they still need that
method to be called, perhaps after doing something else. Some call it
for compatability...

>
> Also, doesn't this still create an _enormous_ portability problem with
> other Smalltalks?
>

Have a look at what Seaside and other cross dialect projects do. I
believe but am not sure they all have some sort of "self basicNew
initialize" on all their top level classes.

- Zulq
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Re: new vs. initialize

Herbert König
Hello Zulq,


 >> Now I read on the WWW that the added sending of #initialize from
 >> Behaviour>>new was added in 3.9.

ZA> Where did you read this? I've been using Squeak for a few years and as
ZA> far as I know the default implementation of #new has always sent
ZA> #initialize.

3.6 does not initialize automatically 3.7 and younger do.



--
Cheers,

Herbert  

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners