Thanks a lot, Eliot!

Bests,

Jordi

> On Wed, Oct 29, 2014 at 9:48 AM, <jdelgado@lsi.upc.edu> wrote:
>
>> Hi all,
>>
>> ------------------------------------------------
>> My question is:
>> One thing I've observed is that local/temporal variables in the blocks
>> passed to #ifTrue:iFfalse are not stored in the separate remote (heap
>> allocated) array, but in the method context (see page 328 of Deep Into
>> Pharo to see what I mean). Is this true?
>
>
> yes.
>
>
>> why?
>>
>
> because the blocks don't really exist. they have been optimized away and
> the control flow implemented using conditional branches and jumps instead
> of closures and polymorphism. Hence there is no other scope to hold
> temps
> in other than the method context (or the block context of a block
> containing optimized blocks).
>
> But realise that the remote temp vector is *only* used for variables that
> are referred to from more than one full scope (method or unoptimized
> block)
> that can change value after they have been closed-over. If a variable is
> closed over but doesn't change then its value is copied into the block,
> and
> ends up in a temporary slot in the block's activation, not in the
> indirection vector.
>
>
>
>> Thanks in advance,
>>
>> Bests,
>>
>> Jordi
>> ------------------------------------------------
>>
>> PS:
>> Now, to put that question in context, here comes a really long "rest of
>> the message" part.
>>
>> We assume we have Continuation class >> #callcc: implemented as:
>> callcc: aBlock
>> ^ Continuation currentDo: aBlock
>> (#callcc: can be found in ContinuationTests, but I prefer to change
>> its location. It does not matter at all where it is).
>>
>> A version of whileTrue: can be implemented with callcc: and no
>> iterative constructs, let's call it BlockClosure >> #whileTrueCC:
>> whileTrueCC: aBlock
>> | cont |
>> cont := Continuation callcc: [ :cc | cc ].
>> self value ifTrue: [ aBlock value.
>> cont value: cont]
>> ifFalse: [^ nil].
>>
>> and you can use it in the same way as #whileTrue:, for example:
>> | n |
>> n := 10.
>> [ n > 0 ] whileTrueCC: [
>> Transcript show: n asString; cr.
>> n := n-1 ]
>>
>> I observed some strange behavior dealing with local variables and
>> continuations. Assume we have:
>>
>> Version 1)
>> whileTrueCC: aBlock
>> | cont tmp |
>> tmp := 0.
>> cont := Continuation callcc: [ :cc | cc ].
>> self value ifTrue: [ aBlock value.
>> Transcript show: 'inside whileTrueCC: -> ',
>> tmp
>> asString; cr.
>> tmp := tmp + 1.
>> cont value: cont]
>> ifFalse: [^ nil].
>>
>> Version 2)
>> whileTrueCC: aBlock
>> | cont tmp |
>> tmp := 0.
>> [ tmp ]. "<-------- Only difference wrt Version 1 !!!! It does
>> nothing, apparently"
>> cont := Continuation callcc: [ :cc | cc ].
>> self value ifTrue: [ aBlock value.
>> Transcript show: 'inside whileTrueCC: -> ',
>> tmp
>> asString; cr.
>> tmp := tmp + 1.
>> cont value: cont]
>> ifFalse: [^ nil].
>>
>> I try both versions with:
>> | n |
>> n := 4.
>> [ n > 0 ] whileTrueCC: [ n := n-1 ]
>>
>> Version 1:
>> It writes in the Transcript:
>> inside whileTrueCC: -> 0
>> inside whileTrueCC: -> 0
>> inside whileTrueCC: -> 0
>> inside whileTrueCC: -> 0
>>
>> Version 2:
>> It writes in the Transcript:
>> inside whileTrueCC: -> 0
>> inside whileTrueCC: -> 1
>> inside whileTrueCC: -> 2
>> inside whileTrueCC: -> 3
>>
>> Which is ok, according to what I understood from Deep Into Pharo. The
>> thing is, why the ifTrue: block does not make tmp behave as when we
>> close
>> it with '[ tmp ]' in version 2?
>>
>
> See above. The compiler is not smart enough to realise that the value of
> [tmp] is discarded, so it thinks there is a block created that closed over
> tmp which may be evaluated at any time (because it could get assigned to a
> variable and used later). So tmp is modified *after* it has been closed
> over (in the while block) and hence the compiler puts it in a temp vector.
>
>
> PS 2: The behavior is *exactly* the same in Version 2 if I close tmp
>> *after* grabbing the continuation, that is, if I go
>> cont := Continuation callcc: [ :cc | cc ].
>> [ tmp ]. "<-------- Only difference wrt Version 1 !!!! It does
>> nothing, apparently"
>> instead of
>> [ tmp ]. "<-------- Only difference wrt Version 1 !!!! It does
>> nothing, apparently"
>> cont := Continuation callcc: [ :cc | cc ].
>>
>
>
> --
> best,
> Eliot
>