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 |
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 |
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. 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 |
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 |
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 |
Free forum by Nabble | Edit this page |