When is a closure a real one? [was: Real closures]

Klaus D. Witzel klaus.witzel at cobss.com
Mon Oct 9 10:54:53 UTC 2006


Thank you master for making this crystal clear!

I think that distiguishing block locals and also scope of locals could  
have been solved by the old (current) compiler+decompiler, but for the  
rest I don't think so.

/Klaus

On Mon, 09 Oct 2006 12:13:15 +0200, Marcus Denker wrote:
>
> On 08.10.2006, at 10:51, Klaus D. Witzel wrote:
>
>> Thank you Mathieu and Phillipe for you pointers and example.
>>
>> Just out of curiosity (and as input for writing accurate yes/no test  
>> cases :) let me ask what is expected by the community (apologies if  
>> this sounds like a silly question ;-) when is a closure a real one:
>>
>> 1] after #fixTemps (or equivalent)
>
> no, fixtemps just copies the home context.
>
> Here is a quote from a mail that I send someone to explain this:
>
> ==============
>
> This brings some of the properties of a closure, but not all. In a way,  
> it's too much.
>
> blocks1 := (1 to: 10) collect: [:ea | [ea]].
> blocks1 collect: [:each | each value]
>
> If you execute this in VW, you get #(1 2 3 4 5 6 7 8 9 10). But in
> Squeak, the :ea
> is just a temp in the method, so the blocks all reference the same
> variable. Thus you get  #(10 10 10 10 10 10 10 10 10 10)
>
> Now that is sometimes really not what you like, so they implemented a
> hack (they are good at that!) called "fixTemps":
>
> blocks1 := (1 to: 10) collect: [:ea | [ea] fixTemps].
> blocks1 collect: [:each | each value]
>
> fixTemps
>         "Fix the values of the temporary variables used in the block  
> that are
>         ordinarily shared with the method in which the block is defined."
>
>         home _ home copy.
>         home swapSender: nil
>
>
> Of course, this does not give you Closure semantics, too, as this now
> makes one new environment per block for all temps of the block...
> whereas with
> Closures, this is not always the case, e.g. when referencing outer
> temps:
>
> |a|
> a := 1.
> b1 := [a].
> b2 := [a] fixTemps.
> a := 3.
> b1 value + b2 value
>
> is Wrong: The fixTemps makes the a in b2 it's own variable, but even
> with Closures, it's the a of the method itself.
>
> Another aspect is that Block Locals like [ | a | ] are from the code
> that is generated indistiguishable from having the | a | defined as
> temps of the method.
>
> myMethod
>     | a |
>     [a].
>
> same as
>
> myMethod
>      [ | a | a]
>
> Some versions ago, Lex Spoon at least fixed the compiler to not
> allow you to reference the block locals and arguments outside the
> block. which was perfectly ok before. But nevertheless, the semantics
> of scoping is Wrong:
>
> tt2
>         | a b |
>         a := [ | t | t := 1].
>         b := [ | t | t ].
>         a value.
>         ^b value.
>
> returns 1, even if each block defines their own (new, completely  
> different) t.
>
> ===================
>
>>
>> 2] after #blockCopy: (is this equivalent to 1?)
>>
>
> blockCopy: is the way to do generate BlockContexts in Squeak. No  
> Clusures.
> Not equivalent to 1).
>
> blockCopy: numArgs
> 	"Primitive. Distinguish a block of code from its enclosing method by
> 	creating a new BlockContext for that block. The compiler inserts into  
> all
> 	methods that contain blocks the bytecodes to send the message
> 	blockCopy:. Do not use blockCopy: in code that you write! Only the
> 	compiler can decide to send the message blockCopy:. Fail if numArgs is
> 	not a SmallInteger. Optional. No Lookup. See Object documentation
> 	whatIsAPrimitive."
>
> 	<primitive: 80>
> 	^ (BlockContext newForMethod: self home method)
> 		home: self home
> 		startpc: pc + 2
> 		nargs: numArgs
>
>
>> 3] after #createBlock: (is this equivalent to 1? to 2?)
>>
>
> This gets you a real closure block (this is from the newcompiler's  
> runtime):
>
> createBlock: env
>
> 	^ BlockClosure new
> 		env: env;
> 		method: self
>
>
> So: old compiler generates code with 2, people add 1 by hand (randomly,  
> as
> bugs show up). Newcompiler generates code with 3, 1 is not needed  
> anymore.
>
>
>       Marcus
>
>
>
>





More information about the Squeak-dev mailing list