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?
why?
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?
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 ].