With my recent venture into spawning Squeak processes, I have a question. From having lurked on the list for many months, I am under the impression that Squeak's blocks are not true lexical closures (and that someone(s) are working toward this). If this is true, then why does something like (forgive any errors - I'm going from memory)
StateMachine>>forkNextTrackProcess
[ | delay | delay _ Delay forMilliseconds: 300. [terminating] whileFalse: [streamingMp3File samplesRemaining = 0 ifTrue: [self nextTrack]. Process waitFor: delay]] fork.
work? 'terminating' is an instance variable of StateMachine, by the way. It would seem that this wouldn't be possible without true lexical closure. I'm no CS major, so please speak slowly and avoid polysyllabic words :-)
Jason,
A BlockContext accesses variables (temporary variables and instance variables) through its home context (a MethodContext). When you call StateMachine>>forkNextTrackProcess a new MethodContext is created on that CompiledMethod. The variable "delay" is a temporary variable stored in the MethodContext, while the variable "terminating" is an instance variable of the receiver.
The issue with BlockContexts in Squeak arises when one stores a BlockContext somewhere and then later tries to evaluate it. When a block is evaluated, there is no new evaluation structure created, and thus it's dangerous to concurrently evaluate the same block (and in fact Squeak disallows this). Two concurrently running blocks would be attempting to access the very same slots for any temporary variables (in the associated home MethodContext). Additionally, if the block takes arguments, after evaluation the block will retain pointers to those arguments because those arguments are also stored in the block's home MethodContext. This can needlessly prevent objects from being garbage collected.
You might open an inspector on a BlockContext (that takes one argument) and it's related home MethodContext. Send the #value: message to the block and observe that it's being stored in the related home MethodContext. You can also refer to a temporary variable in the Block and see that it is also stored in the home MethodContext.
Evaluate the following in a workspace:
| temp | temp := 1. delay := Delay forSeconds: 1. ([ :x | temp := temp + 1. delay wait. x hash ] inspect; home) inspect
You will see an inspector on the BlockContext, and another on it's home MethodContext. The MethodContext will have 2 indexed slots where it stores the values for temp and x respectively. If you evaluate "self value: 'a'" in the BlockContext's inspector (and wait 1 second) you'll notice that these values (in MethodContext) get updated. You'll also noticed that even after the evaluation of the block is complete, that the MethodContext is still holding onto 'a'. If you evaluate:
[self value: 'a'] fork. [self value: 'b'] fork.
In the BlockContext's inspector, you'll get the error: 'Attempt to evaluate a block that is already being evaluated.'
- Stephen
-----Original Message----- From: squeak-dev-admin@lists.squeakfoundation.org [mailto:squeak-dev-admin@lists.squeakfoundation.org] On Behalf Of Jason Dufair Sent: Monday, August 12, 2002 11:32 AM To: squeak-dev@lists.squeakfoundation.org Subject: Lexical closures in Squeak
With my recent venture into spawning Squeak processes, I have a question. From having lurked on the list for many months, I am under the impression that Squeak's blocks are not true lexical closures (and that someone(s) are working toward this). If this is true, then why does something like (forgive any errors - I'm going from memory)
StateMachine>>forkNextTrackProcess
[ | delay | delay _ Delay forMilliseconds: 300. [terminating] whileFalse: [streamingMp3File samplesRemaining = 0 ifTrue: [self nextTrack]. Process waitFor: delay]] fork.
work? 'terminating' is an instance variable of StateMachine, by the way. It would seem that this wouldn't be possible without true lexical closure. I'm no CS major, so please speak slowly and avoid polysyllabic words :-)
-- Jason Dufair - jase@dufair.org http://www.dufair.org/ "In matters of style, swim with the current; in matters of principle, stand like a rock." -- Thomas Jefferson
Jason Dufair jase@dufair.org is claimed by the authorities to have written:
With my recent venture into spawning Squeak processes, I have a question. From having lurked on the list for many months, I am under the impression that Squeak's blocks are not true lexical closures (and that someone(s) are working toward this). If this is true, then why does something like (forgive any errors - I'm going from memory)
StateMachine>>forkNextTrackProcess
[ | delay | delay _ Delay forMilliseconds: 300. [terminating] whileFalse: [streamingMp3File samplesRemaining = 0 ifTrue: [self nextTrack]. Process waitFor: delay]] fork.
work?
It's a fudge to allow slightly easier filing in of code form otheSmalltalks. The 'block temp' is simply moved into the method temps; if you were to look at a context of this form in the debugger you would almost certainly find the values of temps appear to be mixed up.
Anthony Hannan has done a great deal of work towards fixing the lack of proper closures and is currently working on revising his code to work with plain Contexts instead of the explicitly stacked system he worked up. This will make it nice and simple to adapt to any dynamic translation or even static translation system that appears. Should make it nice and easy to do continuations and coroutining too.
tim
Anthony Hannan has done a great deal of work towards fixing the lack of proper closures and is currently working on revising his code to work with plain Contexts instead of the explicitly stacked system he worked up. This will make it nice and simple to adapt to any dynamic translation or even static translation system that appears. Should make it nice and easy to do continuations and coroutining too.
Oh, is that actually happening? Great. Anthony, is that the new version that the swiki page says (or used to say) is coming at the end of July?
Looking forward to it, I've been sending #fixTemps an awful lot lately.
Avi
Avi Bryant avi@beta4.com is claimed by the authorities to have written:
Anthony Hannan has done a great deal of work towards fixing the lack of proper closures and is currently working on revising his code to work with plain Contexts instead of the explicitly stacked system he worked up. This will make it nice and simple to adapt to any dynamic translation or even static translation system that appears. Should make it nice and easy to do continuations and coroutining too.
Oh, is that actually happening? Great.
Anthony, Ian and I (and maybe others? I don;t remember) had a discussion some time ago and concluded that the explicit stack mechanism got in the way of vm implementation flexibility. Sort of an "it breaks Deutsch's rule" situation.
tim
squeak-dev@lists.squeakfoundation.org