RE: Ad-hoc final harvesting for 3.4
Daniel Vainsencher <[email protected]>
| Newsgroups | gmane.comp.lang.smalltalk.squeak.foundation |
|---|---|
| Message-ID | <[email protected]> |
Cool! I think many more things in Squeak should be happening asynchronously. I've been trying to figure out a place to hook that up that wouldn't require people to be always forking things explicitly, and the event handling mechanism sounds like a good solution to that problem... Daniel Andreas Raab <[email protected]> wrote: > Hi Rob, > > > 3) Weak message sends and conversion of the NuBlu events to use them. > > Ever looked at EventMessageSet?! I did this for probably the exact same > reasons that you are using weak messages sends now. And yet, neither is > not going to solve your problems ;-( > > Seriously, did you ever find the time to look closely at how this is > handled in the event stuff that I did a while back (it is now in > Croquet)?! The problem with the NuBlue (and any other event) framework > is that it does not allow the subscriber to reflect about its > subscriptions. In other words, if I have a window and a button and say: > > button on: #click send: #close to: window. > > then what I say is that the button should tell the window to close when > I click on it. And of course, the button has to know the window in order > to do this. And while this is a nice first-order theory it is > problematic if we close that window by any other means (in which case we > may want to stop the subscription) and naturally, the button will hold > on to the window for the rest of its live. This is the problem which you > are trying to solve with weak references but it is conceptually wrong. > > The problem is that #click is really a trigger for a method (script) in > the window which may happen asynchronously. And this script is clearly > owned by the window and not by the button and that's what all of these > event frameworks never take into account. With the model that I built > this is different (and not only in this respect ;-) Here, the subscriber > always remembers its registrations (messages) *strongly* and the > publisher always remembers the subscriptions *weakly* (by default). This > has various advantages, an obvious one being that if the subscriber goes > away so does its subscription (this is what you are trying to do with > weak refs) and the publisher is not bothered by it [*1]. However, what's > even more important is that in a case like the above, the window can > reflect about its subscriptions and cancel them if it gets closed > without having to know any "external subscriptions" (e.g., added by > someone else). > > [*1] I find it _extremely_ questionable to raise an error by default > here. There may be a few applications which need to know about it but by > and large I would expect people to get really confused and say "yeah, of > course it's gone that's what it *ought* to do". For those who do it is > utterly trivial to provide a different subscription (MessageSend > subclass). > > In Croquet, the above example would look like: > > window startScript: #close when: {button. #click}. > > which tells the window to start the #close script when the button is > clicked. [Slight side note here: #startScript denotes an asynchronous > signal; #runScript a synchronous one. So the exact equivalent would be > "window runScript: #close when: {button. #click}" but I haven't used > synchronous signals in about a year except for debugging]. The magic is > now that the window could do something like > > Window>>close > super close. "to get rid of it" > self stopScript: #close. > > in order to cancel its "subscription" (I don't like the term in this > context but it's useful to show the similarities). Or even more > radically (and that's code I am really using): > > Window>>destroy > "I shall be destroyed. Stop all scripts" > self scripts do:[:script| self stopScript: script]. > > This latter makes it impossible to have any pending references if the > window should be destroyed. But there is even more fun stuff you can do > with this. Consider that if we close the window, we want to put into the > trash and be able to get it back. The button should of course work if we > get it back. How can we solve this problem?! Well, here's one solution: > > Window>>initialize > "Set me up in a way that I will only run #close > scripts while I am in the world" > "pause close script when I get out of the world" > self pauseScript: #close when: {self. #outOfWorld}. > "resume close when I get back in" > self resumeScript: #close when: {self. #intoWorld}. > > And this will work for any number of buttons who want to send close to > the window. All of this is only possible because the *window* knows > about the scripts (subscriptions) and not the button. > > There are even more advantages to this (such as for serialization) but I > think this will get you an idea why I think that any kind of > subscription mechanism that doesn't give the subscriber access to its > subscriptions is ultimately doomed to fail - you simply cannot write > fault-tolerant code if you cannot reflect about them. > > Cheers, > - Andreas > > _______________________________________________ > Squeakfoundation mailing list > [email protected] > http://lists.squeakfoundation.org/listinfo/squeakfoundation