For the people following I added a test to show the homeContext of a block

| homeContext b1 |
homeContext := thisContext.
b1 := [| b2 |
          self assert: thisContext closure == b1.
          self assert: b1 outerContext == homeContext.
            self assert: b1 home = homeContext.
          b2 := [self assert: thisContext closure == b2.
                    self assert: b2 outerContext closure outerContext == 
homeContext].
                          self assert: b2 home = homeContext.
          b2 value].
b1 value 




> 
> 
> On Tue, Jul 23, 2013 at 2:02 AM, Stéphane Ducasse <[email protected]> 
> wrote:
> thanks!
> It makes a lot of sense.
> I will play with another example because I want to really understand the 
> outerContext of closure vs the home context.
> 
> The outerContext is a link in the static chain.  Each block is created inside 
> some context.  This is the block's outerContext.  If the block is not nested 
> then the outerCOntext will also be the home context  But if the block is 
> nested inside another block activation, then the outerContext refers to that 
> block activation, and the block activation's block's outerContext is the home 
> context.  So there are as many outerContext steps as there are nesting levels.
> 
> | homeContext b1 |
> homeContext := thisContext.
> b1 := [| b2 |
>           self assert: thisContext closure == b1.
>           self assert: b1 outerContext == homeContext.
>           b2 := [self assert: thisContext closure == b2.
>                     self assert: b2 outerContext closure outerContext == 
> homeContext].
>           b2 value].
> b1 value 
> 
> Ignore the "bN appears to be undefined at this point" and evaluate the above. 
>  No assert fails.
> 
> Draw a picture.
> 
> 
> Stef
> 
> On Jul 23, 2013, at 6:58 AM, Clément Bera <[email protected]> wrote:
> 
>> This is because of compilation optimization.
>> 
>> 2013/7/22 Stéphane Ducasse <[email protected]>
>> Hi
>> 
>> when I execute the following
>> 
>> first
>>         "Bexp new first"
>>         | temp |
>>         temp :=  2.
>>         [ temp.
>>         thisContext inspect.] value.
>>         ^ temp
>> 
>> tmp in the inspector is nil and does not hold 2 and I was wondering why.
>> I thought that thisContext was returning the blockContext
>> In the outercontext of thisContext blockClosure, tmp is also nil.
>> 
>>  
>> This is because here 'temp.' is evaluated for effect (the value is not 
>> stored anywhere) and it has no side effect (reading a variable cannot lead 
>> to a modification of state of another object). So the compiler removes it. 
>> As it is removed, it is the same as if it was not in the block. So the block 
>> cannot access temp. Now write 'temp:= #foo' or 'temp foo' you will get it.
>>  
>> first
>>         "Bexp new first"
>>         | temp |
>>         temp :=  2.
>>         [ temp.
>>         temp traceCr.
>>         thisContext inspect.] value.
>>         ^ temp
>> 
>> output 2 on the transcript.
>> 
>> In this case 'temp.' is still removed, but the value of temp still need to 
>> be copied in the block for ' temp traceCr.'.'temp traceCr' is also evaluated 
>> for effect, but has the side effect to output the transcript, so the 
>> compiler cannot remove it.
>> 
>> Basically the is very few things that the compiler removes, and one of them 
>> is variable read for effect, because you are sure it cannot lead to any 
>> issue.
>>  
>> Stef
>> 
>> 
> 
> 
> 
> 
> -- 
> best,
> Eliot

Reply via email to