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
>