Subject: Re: primitives In-Reply-To: Your message of Wed, 30 Jan 91 19:41:05 -0500 Reply-To: Urs Hoelzle email@example.com Message-Id: <CMM.0.88.665431692.urs@> Status: RO
Are primitives like _RemoveSlots: and _AddSlots: going to be useable within methods in the next release?? This would be cool, because it would help with data inheritance.
No (see the release message). They do work in our current system (i.e. you can change objects while the program is running), but we want thing to stabilize a bit before putting them into a release.
I have been thinking about this as it seems to me that not being able to modify objects at runtime makes it impossible to develop a complete programming environment ( like Smalltalk's ) for Self.
Note that I sent this mail last January...so, just to avoid any confusion: yes, the upcoming release will absolutely definitively have the ability to modify objects at runtime.
There seems to be a language definition problem and a implementation problem. What happens if modifying the object alters the lookup of methods that are already on the stack? You could say that they should not be affected and that only messages sent from now on must reflect the altered object.
Suppose that foo = (| bar = ( a. b. ). a = ( 'a' print ). b <- nil |) and foo and a are on the stack (e.g. the process is suspended just before the send of 'print').
Now suppose some other process does foo _Define: (| a = ( 'A' print). b = ( 'b' print ) ). What should happen when the suspended process continues?
Well, bar and a are already on the stack, i.e. their activation objects have been created by cloning the (old definition of) their respective method. Thus, the _Define won't affect them directly because the clones are independent of the original just like for every other Self object. So a will send the print message and return, and then bar will send the 'b' message. This will invoke the new (current) definition, of course, just as you would expect from an interpreter.
The system keeps dependency information to keep track of the fact that the machine code for bar depends on b being a data slot. During the _Define:, bar's code is marked as "outdated", and it's stack frame is marked. When control returns to bar (after the change), a trap handler is invoked which recompiles bar before continuing execution.