A few weeks ago we had a useful discussion about the problems of handling pool dictionaries and concluded that it might be useful to use classes to do the job. Andreas duly produced a prototype for us and included a really neat cleanup of scope handling.
I've been checking out the code and it seems a nice step towards a solution - we should adopt it. I now have a revised version that:- a) is fudged to make sure that all the pools are installed in the image. This is a simplistic approach pro-tem until we solve the problem of dependency in SM1.1 - the classes are small and at least it would mean we can rely on pools being there for now. b) adds some changes to keep the 'explain' utilities working. c) simply prevents filing out of the new kind of pools dicts; we need to work out what to do here. We could of course file out the class of the pool dict but I think that is probably not correct. d) fix Smalltalk>poolUsers to handle the new pool classes.
There are some methods that need discussion here:-
ReadWriteStream & GZipSurrogateStream>fileOutClass:andObject: & ReadWriteStream >fileOutClass:andObject:blocking:, SmartRefStream>appendClassDefns, SystemOrganizer>fileOutCategory:on:initializing:, Class>fileOutAsHtml:, Class>fileoutSharedPoolsOn: - all may need simplifying to drop the pool fileout.
Class removeSharedPool: won't work - is it useful anymore? Not sent and changing pools for a class is done by redfining class and using #sharing:
The file is http://sumeru.stanford.edu/tim/pooters/SqFiles/deltas/DeclarativePools- 4.sar
tim
Hi tim
Great. I did not have the time to look at it but I trust your initiative. On Friday, May 30, 2003, at 11:23 PM, Tim Rowledge wrote:
A few weeks ago we had a useful discussion about the problems of handling pool dictionaries and concluded that it might be useful to use classes to do the job. Andreas duly produced a prototype for us and included a really neat cleanup of scope handling.
I've been checking out the code and it seems a nice step towards a solution - we should adopt it. I now have a revised version that:- a) is fudged to make sure that all the pools are installed in the image. This is a simplistic approach pro-tem until we solve the problem of dependency in SM1.1 - the classes are small and at least it would mean we can rely on pools being there for now. b) adds some changes to keep the 'explain' utilities working. c) simply prevents filing out of the new kind of pools dicts; we need to work out what to do here. We could of course file out the class of the pool dict but I think that is probably not correct.
d) fix Smalltalk>poolUsers to handle the new pool classes.
I think that for once this is functionality that will stay in SystemDictionary :)
There are some methods that need discussion here:-
ReadWriteStream & GZipSurrogateStream>fileOutClass:andObject: & ReadWriteStream >fileOutClass:andObject:blocking:, SmartRefStream>appendClassDefns, SystemOrganizer>fileOutCategory:on:initializing:, Class>fileOutAsHtml:, Class>fileoutSharedPoolsOn:
- all may need simplifying to drop the pool fileout.
I really have a problem with the idea of having Class>>fileOutAsHtml: I think that the fileOut should be rethink: may be we should have a fileOuter, HTMLFileOuter... This code is also really ugly, I had really hard time to create a new fileOuter that was compatible with VW and there is all kinds of bad dirty logic full of if HTML.
Finally I was really wondering was a class such as SmartRefStream has reference to PopUpMenu...... but this another discussion.
If somebody has ideas to propose a cleaner solution please talk. As a first step could we agree to get rid of the fileout as html feature?
Stef
Class removeSharedPool: won't work - is it useful anymore? Not sent and changing pools for a class is done by redfining class and using #sharing:
The file is http://sumeru.stanford.edu/tim/pooters/SqFiles/deltas/ DeclarativePools-4.sar
tim
tim@sumeru.stanford.edu
Stephane Ducasse wrote:
I really have a problem with the idea of having Class>>fileOutAsHtml: I think that the fileOut should be rethink: may be we should have a fileOuter, HTMLFileOuter...
I like the way that Dandelion does it, using separate introspectors. These then use different strategies (reflection, reading annotated comments, etc.) to answer queries from the outputters. It seems clear to me that structured introspection should be separate from the things being examined, and that the output should be separate from those. Separating reflection from Behavior as well (as has been suggested here before) might also make sense.
This code is also really ugly, I had really hard time to create a new fileOuter that was compatible with VW and there is all kinds of bad dirty logic full of if HTML.
Finally I was really wondering was a class such as SmartRefStream has reference to PopUpMenu...... but this another discussion.
It clearly shouldn't have. An Exception of some sort would probably be best here. The World's default handler for this exception could be to pop up the dialog.
Likewise, entities like ChangeSet really shouldn't be doing UI work themselves.
If somebody has ideas to propose a cleaner solution please talk. As a first step could we agree to get rid of the fileout as html feature?
I could see removing it from Class and putting it somewhere else, then sticking it into a package.
Hi ned
I like the way that Dandelion does it, using separate introspectors. These then use different strategies (reflection, reading annotated comments, etc.) to answer queries from the outputters. It seems clear to me that structured introspection should be separate from the things being examined, and that the output should be separate from those. Separating reflection from Behavior as well (as has been suggested here before) might also make sense.
Thanks for the pointer I will have a look. We could do that in several steps: first having dedicated outputters.
This code is also really ugly, I had really hard time to create a new fileOuter that was compatible with VW and there is all kinds of bad dirty logic full of if HTML. Finally I was really wondering was a class such as SmartRefStream has reference to PopUpMenu...... but this another discussion.
It clearly shouldn't have. An Exception of some sort would probably be best here. The World's default handler for this exception could be to pop up the dialog.
Likewise, entities like ChangeSet really shouldn't be doing UI work themselves.
If somebody has ideas to propose a cleaner solution please talk. As a first step could we agree to get rid of the fileout as html feature?
I could see removing it from Class and putting it somewhere else, then sticking it into a package.
Whilst I understand the urge to tidy up some of the filing out system, the bit that I consider reasonably urgent is deciding what to do about the filing out of pools; it needs to be resolved soon to make the new declarative pools code ready to issue.
The current scheme files out a simple declaration of the dictionary at the front of the fileout. This provides some hope of the filein working if the image doesn't already have the pool, though it does lead to the potential problem of 'corrupting' a newer pool definition. If we move to SharedPool classes then we need to at least change what gets filed out and probably reconsider if the pool should actually be included with the fileout. I _think_ I prefer the idea of using SM1.1 to handle the dependency issue where there are pools shared across packages (for example balloon3d needs B3DEngineConstants and so does b3dplugins) rather than including the class in both packages. For now, as a temporay palliative, I strongly suggest we just include all the pools classes in the image at the cost of a few bytes.
So, my proposal:- drop the pool filing out code in all the assorted fileout methods. track down all shared pools and convert them to subclasses of SharedPool (TextConstants and WonderlandConstats are two I've spotted) and just put them in the image. update packages involving pools to reflect the new format by checking the latest update number and not using any declaration of pool dictionaries if appropriate.
tim
Hi tim
I agree with you but right now I'm in time shortage period. So go ahead.
Stef
On Saturday, May 31, 2003, at 09:49 PM, Tim Rowledge wrote:
Whilst I understand the urge to tidy up some of the filing out system, the bit that I consider reasonably urgent is deciding what to do about the filing out of pools; it needs to be resolved soon to make the new declarative pools code ready to issue.
The current scheme files out a simple declaration of the dictionary at the front of the fileout. This provides some hope of the filein working if the image doesn't already have the pool, though it does lead to the potential problem of 'corrupting' a newer pool definition. If we move to SharedPool classes then we need to at least change what gets filed out and probably reconsider if the pool should actually be included with the fileout. I _think_ I prefer the idea of using SM1.1 to handle the dependency issue where there are pools shared across packages (for example balloon3d needs B3DEngineConstants and so does b3dplugins) rather than including the class in both packages. For now, as a temporay palliative, I strongly suggest we just include all the pools classes in the image at the cost of a few bytes.
So, my proposal:- drop the pool filing out code in all the assorted fileout methods. track down all shared pools and convert them to subclasses of SharedPool (TextConstants and WonderlandConstats are two I've spotted) and just put them in the image. update packages involving pools to reflect the new format by checking the latest update number and not using any declaration of pool dictionaries if appropriate.
tim
Tim Rowledge, tim@sumeru.stanford.edu, http://sumeru.stanford.edu/tim World Ends at Ten - Pictures at 11 on Fox News!
Hi Tim,
drop the pool filing out code in all the assorted fileout methods. track down all shared pools and convert them to subclasses of SharedPool (TextConstants and WonderlandConstats are two I've spotted) and just put them in the image.
I agree. The reason I haven't touched any of the remaining pools are mostly that WonderlandConstants uses lower case constants that I'm unsure about how to deal with it and TextConstants includes all of the TextStyles which is problematic.
Any ideas about how to deal with the two issues would be appreciated.
Cheers, - Andreas
"Andreas Raab" andreas.raab@gmx.de wrote:
TextConstants includes all of the TextStyles which is problematic.
I see a couple of dozen places where 'TextContants' is specifically used as opposed to values within it. The simplistic answer here is to add some protocol to the shared pool to handle the following:-
#at: as in dictionary access (TextMorphEditor>changeStyle*, Array>objectForDataStream:, EToySystem class>fixComicCharacters*, TextStyle>collectionFromFileNamed:*, ParseNode>printSingleComment:on:indent: - really weird use to get tab width)
#at:ifAbsent: (TextStyle class>named:*, ProgressMorph>fontOfPointSize:*, TextStyle>collectionFromFileNamed:, StrikeFont>objectForDataStream: - abuse of TextConstants as a preference)
#at:put: (TTFontReader class>installTTF:asTextStyle:sizes:*, Text class>initialize, Text class>initTextConstants, BDFFontReader class>installX11Fonts*, Preferences class>setSystemFontTo:*, TextStyle class>changeDefaultFontSizeBy:*, TextStyle class>initDefaultFontsAndStyle*, FontSet class>installAsTextStyle*, FontSet class>installAsDefault*)
#removeKey:ifAbsent: (SystemDictionary>makeExternalRelease* - are we going to keep this?, SystemDictionary>discardOddsAndEnds* - surely this will soon disappear?, SystemDictionary>makeSqueaklandRelease* ??)
#select:[] (Utilities class>actualTextStyles*, Utilities class>knownTextStyles*, StrikeFont class>familyNames* - same as Utilities class>knownTextStyles except for asSortedCollection instead of asSortedArray and both of them ought to be replaced by TextStyle class methods, UpdatingStringMorph>setFontStyle*) - all of these are to allow finding a TextStyle of a certain name
19 out of 25 uses are to do TextStyle related stuff, leading me to the staggering conclusion that maybe something needs a bit of a cleanup. After all, when we have 'TextStyle default' _and_ 'TextConstants at: #DefaulTextStyle' AND they may not be the same I think that implies a bit of a mess. Since TextStyle is a class and already globally accessible I'm not sure what the value of keeping instances of styles 'hidden' in TextConstants.
Anybody want to offer suggestions for improvements?
tim
As I mentioned in a recent message, there is a problem with changing over to using these nice declarative pools classes. There's no particular problem with the new pools themselvs, it's an issue of our old friend backwards compatability.
Is _anybody_ actually interested in this problem? I could do with some help working out the issues and finding suitable solutions - if any. My view is something along the lines of 'make the change and fix the broken code' but I wouldn't want to impose my views on people willy-nilly. Perhaps a change like this can be piled up along with the new image format and massive VM back-compat rework? Perhaps it shouldn't be done?
tim -- Tim Rowledge, tim@sumeru.stanford.edu, http://sumeru.stanford.edu/tim "How many Teela Browns does it take to change a lightbulb?" "Stupid question."
Hi Tim,
As I mentioned in a recent message, there is a problem with changing over to using these nice declarative pools classes. There's no particular problem with the new pools themselvs, it's an issue of our old friend backwards compatability.
Well, you can't make an omelette without breaking a few eggs ;-) But I don't see any particular problems with adopting an interim solution. E.g., use declarative pools for everything that hurts us right now and leave everything else as is (which means we won't have to worry about WonderlandConstants or TextConstants right now). As far as I can tell, there may be a few problems in some obscure places (such as you noticed in SystemDictionary>>makeExternalRelease or similar) but these don't seem to be overly problematic (as in: relatively easy to fix).
Is _anybody_ actually interested in this problem? I could do with some help working out the issues and finding suitable solutions - if any.
See above. I'm not certain I would *want* to change everything right now (besides - we will have to support "dictionary style pools" for some time to come anyways).
My view is something along the lines of 'make the change and fix the broken code' but I wouldn't want to impose my views on people willy-nilly. Perhaps a change like this can be piled up along with the new image format and massive VM back-compat rework?
See above. Gradual adoption seems possible to me and (although I haven't tried it yet) I'm pretty certain that it will work even with stuff like Anthony's closure compiler.
Cheers, - Andreas
"Andreas Raab" andreas.raab@gmx.de wrote:
Hi Tim,
[snip]
Well, you can't make an omelette without breaking a few eggs ;-)
That's certainly true and I don't mind breaking eggs so long as people agree they're the right eggs and that we all want omelettes.
But I don't see any particular problems with adopting an interim solution. E.g., use declarative pools for everything that hurts us right now and leave everything else as is (which means we won't have to worry about WonderlandConstants or TextConstants right now). As far as I can tell, there may be a few problems in some obscure places (such as you noticed in SystemDictionary>>makeExternalRelease or similar) but these don't seem to be overly problematic (as in: relatively easy to fix).
The TextConstants stuff is almost completely separable so far as I can see and I think we (as in 'I') should do something about it anyway..
See above. I'm not certain I would *want* to change everything right now (besides - we will have to support "dictionary style pools" for some time to come anyways).
Ah, now that's the bit that bothers me; working out how to support the Dictionaries used in older code that gets filed in. I'll try to elucidate my worry:- Let's say we have converted GZipConstants to be one of your nice SharedPool subclasses and now we try to load a package where the old dictionary of GZipConstants was included in the fileout (I suspect this is pretty rare but not infinitely so). The file will start with
Smalltalk at: #GZipConstants put: Dictionary new! GZipConstants at: #foo put: 'bar'!
and so on. Thus we lose our nice class and all the values are over-written. Actually of course this is a generic problem with the way pools have been filed out and back in; I rather wish that code had not been added at all. I hope to find that there are no packages that took advantage of it!
Of course, there is a possibility of using ReadOnlyBindings for the class and trapping the exception and handling it to skip all the'bad' stuff. However, as we've been discussing elsewhere there's no guarantee that a class is held in such a binding so some extra work is needed.
As a rather different way of handling this, perhaps it is worth reconsidering an earlier plan we discused, that of using classes to _define_ the pools rather that _be_ the pools. I don't think it's as nice as your SharedPool classes but it does at least avoid the hassles of handling the filein of old dictionaries. It doesn't solve the problem of out of date ones but we can't often have everything. Using pool-definer classes does at least give us the 'ownership' of pools, a place from where they came and a sort of guardian of their contents, which is good. Filing in a pool-definer would create the pool as part of the class initialize method.
I'm not sure which is better in the long term; I prefer the elegance of SharedPool but don't like the filein hassles. Any other opinions before we spend too much time on a dead-end?
tim -- Tim Rowledge, tim@sumeru.stanford.edu, http://sumeru.stanford.edu/tim Strange OpCodes: PHP: Put Hackers into Privileged mode
Ah, now that's the bit that bothers me; working out how to support the Dictionaries used in older code that gets filed in. I'll try to elucidate my worry:- Let's say we have converted GZipConstants to be one of your nice SharedPool subclasses and now we try to load a package where the old dictionary of GZipConstants was included in the fileout (I suspect this is pretty rare but not infinitely so). The file will start with
Smalltalk at: #GZipConstants put: Dictionary new! GZipConstants at: #foo put: 'bar'!
To be honest, I don't see the problem. For those pools which are effectively managed by the system (e.g., TextConstants, GZipConstants, ZipConstants etc) any attempt to replace them in Smalltalk would *rightfully* raise an error (think about what would happen if the pool has evolved and you try to file in an older version). Looking over lots of code I've not found a single place where the currently converted pools were used through #at: or another dictionary protocol (which is precisely the reason why I haven't touched TextConstants as it contains the TextStyles and some packages *do* register new ones) and so while there are chances that there's some code out there which uses the dictionary protocol I think that they are *extremely* small. So for the "system" set of pools I feel pretty safe as long as we don't touch TextConstants too early on.
About pools managed somewhere else: Here I claim that it's the responsibility of the package maintainer to decide whether or not to use declarative pools. While I think that we should generally encourage the use of declarative pools I am not going to require people to switch at some definitive point. If some package runs into any problems related to dictionary pools then I'd say that the package maintainer screwed up (both by not protecting the pool from being filed in by someone else as well as allowing abuse of the above kind).
BTW, for any package which I (officially or not) maintain I herewith declare that any use of Dictionaries for pools is abuse of the worst kind and will be punished with one blue screen of death per every ten lines of executed code! (if you're not running windows substitute the appropriate color)
Of course, there is a possibility of using ReadOnlyBindings for the class and trapping the exception and handling it to skip all the'bad' stuff.
We may want to do this though I think it's a rather unlikely situation.
As a rather different way of handling this, perhaps it is worth reconsidering an earlier plan we discused, that of using classes to _define_ the pools rather that _be_ the pools.
Na. Break those eggs! They stink anyway!
I don't think it's as nice as your SharedPool classes but it does at least avoid the hassles of handling the filein of old dictionaries.
Again, for those pools which were converted I think we're either fine or people should absolutely fix that code which relies on any of the nasty abuses of pool dictionaries. Any other code is not affected at all so unless you abuse an existing pool all is fine. And when you abuse it I don't care the least bit if your code breaks when filing it in.
I'm not sure which is better in the long term; I prefer the elegance of SharedPool but don't like the filein hassles. Any other opinions before we spend too much time on a dead-end?
I don't see neither a dead-end nor a problem here. Show me a couple of practical examples of the problems you see (we've got roughly 250 packages on SqueakMap) and if you find more than two let's talk about it again.
Cheers, - Andreas
"Andreas Raab" andreas.raab@gmx.de wrote:
To be honest, I don't see the problem. For those pools which are effectively managed by the system (e.g., TextConstants, GZipConstants, ZipConstants etc) any attempt to replace them in Smalltalk would *rightfully* raise an error
It doesn't seem to in my latest image; 'Smalltalk at: #TextConstants put: Dictionary new' works just fine. It doesn't break any _compiled_ code of course because the old associations are still there but any code compiled after that will get the new (if any) association. IFF the SharedPool classes were protected in ReadOnlyBindings we'd get an error (I just tested by using | readOnly readWrite | readWrite _ (SharedPool withAllSubclasses asArray collect:[:cl| cl name]) collect:[:s| Smalltalk associationAt: s]. readOnly _ readWrite collect:[:x| (ReadOnlyVariableBinding key: x key value: x value)]. readOnly elementsExchangeIdentityWith: readWrite. to confirm it still works ok) and can do whatever; if people are ok with it simply being an Error that's fine with me.
(think about what would happen if the pool has evolved and you try to file in an older version).
That's one of the things that makes me dislike the current code - terrible opportunity for corruption.
[snip]
So for the "system" set of pools I feel pretty safe as long as we don't touch TextConstants too early on.
I agree that we're pretty safe but, spank my whippet and call me Granny, I worry about these possibilities. Thinking of TextStyle - yuck. So much ugly code relating to use and abuse of TextStyles. Boy does that stuff need cleaning up.
[snip]
As a rather different way of handling this, perhaps it is worth reconsidering an earlier plan we discused, that of using classes to _define_ the pools rather that _be_ the pools.
Na. Break those eggs! They stink anyway!
I agree in general. Stinky eggs need throwing out.
I don't see neither a dead-end nor a problem here. Show me a couple of practical examples of the problems you see (we've got roughly 250 packages on SqueakMap) and if you find more than two let's talk about it again.
Well, the first one I can think of doesn't simplistically use the 'Smalltalk at:#FooDict put: Dictionary new' incantation but it does result in the pool being made as a Dictionary and filling it in. You probably know of it; it's called Balloon3D.sar :-)
Nonetheless I think I agree mostly that it is probably worrying too much to obsess on this. Perhaps I'll write-protect the 'system' pools and let the rest look after themselves for now.
tim -- Tim Rowledge, tim@sumeru.stanford.edu, http://sumeru.stanford.edu/tim APL is a write-only language. - Roy Keir
Tim,
any attempt to replace them in Smalltalk would *rightfully* raise an error
It doesn't seem to in my latest image; 'Smalltalk at: #TextConstants put: Dictionary new' works just fine.
I know. (I said it "would" rightfully raise an error if we make them r/o)
I don't see neither a dead-end nor a problem here. Show me a couple of practical examples of the problems you see (we've got roughly 250 packages on SqueakMap) and if you find more than two let's talk about it again.
Well, the first one I can think of doesn't simplistically use the 'Smalltalk at:#FooDict put: Dictionary new' incantation but it does result in the pool being made as a Dictionary and filling it in. You probably know of it; it's called Balloon3D.sar :-)
Whoa! Wait a second. The pool is owned by Balloon3D.sar and therefore it is perfectly okay for that package to define and use the pool in any way it wants. That's exactly why I want to have the compatibility bridge so that packages which in fact define and use their own pools can continue to function.
Cheers, - Andreas
On Friday, June 6, 2003, at 02:46 PM, Andreas Raab wrote:
Whoa! Wait a second. The pool is owned by Balloon3D.sar and therefore it is perfectly okay for that package to define and use the pool in any way it wants. That's exactly why I want to have the compatibility bridge so that packages which in fact define and use their own pools can continue to function.
Oh, I know, I was just tweaking your nose a little. Besides, if and when we adopt all this we've got the revised .sars ready with the b3d plugins and shared pool separated out.
I'll make the SharedPools r/o explicitly for the next prototype but it's a bit cumbersome and any new ones would need manual intervention.
tim
Tim Rowledge wrote:
I'm not sure which is better in the long term; I prefer the elegance of SharedPool but don't like the filein hassles. Any other opinions before we spend too much time on a dead-end?
This is a case where, IMO, the mentality of "burn the disk packs" is completely justified. In other words, forget about legacy code support-- just do the best technical thing.
And IMO, having a class *be* the pool rather than just *define* the pool is best technically.
But that's just my opinion.
I realize that I might be treading on the robes of wizards here, but I can never resist asking a few "dumb" questions.
At 16:20 -0700 06/05/2003, Tim Rowledge wrote:
Let's say we have converted GZipConstants to be one of your nice SharedPool subclasses and now we try to load a package where the old dictionary of GZipConstants was included in the fileout (I suspect this is pretty rare but not infinitely so). The file will start with
Smalltalk at: #GZipConstants put: Dictionary new! GZipConstants at: #foo put: 'bar'!
So the problem -- if I understand what's been said so far -- is that our nice global variable GZipConstants that used to point to our nice new class now refers a dictionary instead, and any attempt to compile new code referencing the GZipConstants class will instead end up referencing the dictionary, and that would be be bad. It would be particularly bad because the problem might not be discovered for weeks (how often do I compile code that references GZipConstants?), and when I discover the problem, I've completely forgotten that I ever *filed in some package or other ...
My naive question was going to be: can't we just fix the filein code so that any attempt to execute Smalltalk at: aSymbol where aSymbol is already bound to a class would be an error. This would generate the error at the earliest possible time, when it would be relatively easy to fix.
Then I thought: isn't that EXACTLY what the read-only variable binding stuff is designed to accomplish (in addition to stopping me from accidentally doing SmallInterger := 3 in a workspace).
So I started to look at ReadOnlyVariableBinding, and yes, it does just the right thing.
BUT I can't find any place that *uses* ReadOnlyVariableBinding. That is, the class is used in LookupKey >> beReadOnlyBindingAnnouncing: which is sent by LookupKey >> beReadOnlyBinding which does not appear to be sent at all in my 3.4 image.
Of the 2084 bindings in Smalltalk, 2056 are to classes. Most of these are ReadOnlyVariableBindings, but
Smalltalk associations reject: [:a | (a value isKindOf: Class) ==> [a isKindOf: ReadOnlyVariableBinding] ]
388 of them are not. I would expect that somewhere down in ClassBuilder, when installing a newly compiled class in Smalltalk, the binding would be made readOnly, but I still can't find that code, although I can find the code that handles the Error that is raises when a ReadOnlyVariableBinding is updated.
So, finally, my "naive" question:
(1) When are ReadOnlyVariableBindings created, (2) Why is this mechanism not applied to those other 388 classes, and (3) If ReadOnlyVariableBindings were used uniformly, would they not solve the problem of turning PoolDictionaries into classes and then protecting them from overwriting
Along the way, I encountered a need to clean up the various kinds of Association, for example, so that ReadOnlyVariableBindings print as a -> b. But that is another topic.
Andrew
(1) When are ReadOnlyVariableBindings created,
Never. I just had a discussion with Tim about where exactly they should be created.
(2) Why is this mechanism not applied to those other 388 classes, and
Because they were "manually" installed.
(3) If ReadOnlyVariableBindings were used uniformly, would they not solve the problem of turning PoolDictionaries into classes and then protecting them from overwriting
They would, but in turn they would break any attempt to file in code which (accidentally or not) attempts to store over them. Which is exactly what I meant by "break those stinky eggs".
Along the way, I encountered a need to clean up the various kinds of Association, for example, so that ReadOnlyVariableBindings print as a -> b. But that is another topic.
It used to print that way. I don't remember when this got changed (but likely to indicate that these bindings are NOT associations).
Cheers, - Andreas
"Andreas Raab" andreas.raab@gmx.de wrote:
(1) When are ReadOnlyVariableBindings created,
Never. I just had a discussion with Tim about where exactly they should be created.
(2) Why is this mechanism not applied to those other 388 classes, and
Because they were "manually" installed.
Andrew is raising a good question though; given that when the relevant changeset was installed _all_ the classes in the system were protected as a result of the chageset postscript, we ought to have a decent reason (or at least, explanation) why we now have some protected and some not. I recall you explaining to me that there were (back then) some situations where it was not appropriate and that maybe such did not exist anymore. Can you (or anyone?) recall the problem? Can we now change ClassBuilderto use ReadOnlyBindings for creation of classes?
tim -- Tim Rowledge, tim@sumeru.stanford.edu, http://sumeru.stanford.edu/tim Strange OpCodes: BOZO: Use Multics operating system
At 16:29 -0700 06/06/2003, Andrew P. Black wrote:
Along the way, I encountered a need to clean up the various kinds of Association, for example, so that ReadOnlyVariableBindings print as a -> b. But that is another topic.
Ok, so let's switch topic. I haven't been Squeaking for a bit, so please be patient. I see this as a modest contribution to the Kernel Cleaning Project, and it has given me an appreciation of how difficult a task KCP is.
I decided, just for fun, to try to rationalize Association, ReadOnlyVariableBinding (which should probably be called ReadOnlyAssociation), and the two kinds of WeakAssociation.
First I wrote some tests, which duly failed in six places:
with Associations, WeakKeyAssociations, and ReadOnlyVariableBindings, #one->1 is equal to #one->2 with ReadOnlyVariableBindings and WeakValueAssociations, only the key is printed by printOn:
I think that I know what = should do, but now I'm asking the customer: how should ReadOnlyVariableBindings and WeakValueAssociations print? I am willing to believe that some distinction between ReadOnlyVariableBindings and ordinary associations is desirable, but I don't believe that omitting the value is the right distinction! I suggest either
#one->1
just like an association, or
#one=>1
to indicate the unchanging character of the mapping. I claim that WeakValueAssociations should print just like WeakKeyAssociations, i.e., the same as Associations.
Note that storeOn: passes my tests in every case, because here the actual class name is printed on the stream.
OK, so I have implemented several new classes:
APBAbstractAssociation #() APBAssociation #('value') APBReadOnlyVariableBinding #() APBHalfWeakAssociation #() APBWeakKeyAssociation #() APBWeakValueAssociation #()
and they pass my tests.
So now the next question is: how do I install them in my image, that is, use them to replace the corresponding classes without the APB prefix. I can't rename APBAssociation to Association, because Association already exists. I can't delete the class Association, or rather, I can, but it crashes my image silently. I would think that moving Association to Undefined, and then renaming APBAssociation to Association, followed by 'becoming' all of the old Associations to the new Associations might work, but I'm not clear how to do this in detail.
Finally, what is the appropriate stage to hand this off to the KCP? Right now I have a nice clean change set, but all it does is define a few tests and some APB-classes. If I succeed in installing all of this stuff, I won't have that any more. What would KCP like?
What's a weekend Squeaker to do? (OK, the answer is probably to start with a less invasive project. But I plan to have a student this summer work on installing the Collections that Nathanael and I wrote with traits into an image *in place of* the ordinary collections. This will be a similarly invasive change, and I would like to figure out how to do it.)
Andrew
Ted, your initials are the last ones attached to this method, do you know anything helpful about it? I don't want to bother changing it if it is actually sometinhg we ought to remove instead.
Class removeSharedPool: won't work - is it useful anymore? Not sent and changing pools for a class is done by redfining class and using #sharing:
tim
squeak-dev@lists.squeakfoundation.org