# Continuations

**URL:** <https://www.ruby-forum.com/t/continuations/159277>\
**Category:** Ruby\
**Created:** [February 2, 2009, 11:11pm UTC](https://www.ruby-forum.com/t/continuations/159277 "2009-02-02T23:11:45Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![paulf](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/eb9ed0/32.png) [@paulf](https://www.ruby-forum.com/u/paulf)\
**Post date:** [February 2, 2009, 11:11pm UTC](https://www.ruby-forum.com/t/continuations/159277/1 "2009-02-02T23:11:45Z")

</div>

Please help. I’m totally confused by following behaviour with regard to  
continuations (Ruby 1.8.7) My goal was to simply jump between two loops,  
which worked fine. But I do not really understand this behaviour:

def loller(id, num, that)  
loop do  
puts id.to\_s + " " + num.to\_s  
num += 1  
sleep(0.5)

```
    # why do i need to update 'that' here, but not 'well' in the

```

while loop??  
# callcc { |here| that.call(here) }, w/o assignment doesn’t work  
here  
that = callcc { |here| that.call(here) }

```
    # any subsequent calls to 'well' (well.call) should return to

```

THIS POINT  
# with num == 35  
# since I never reassign the continuation referenced by ‘well’

```
end

```

end

i = 0  
well = callcc { |c| loller(1,34,c) }

while true

```
# why don't I need: well = callcc { |here| well.call(here) }
# callcc { |here| well.call(here) }, w/o assignment works here!!!
callcc { |here| well.call(here) }
puts "back to root " + i.to_s
i += 1

```

end

This program increases a simple counter in each loop, and prints it.  
However, I do not understand why this works, since I am not reassigning  
the continuation returned by the loop in function “loller”. The call  
made from the while-loop was looking like this to begin with:

well = callcc { |here| well.call(here) }

Which gives the same result, even when i remove the assignment. That  
means the ‘well’ variable still references the original continuation  
i.e. value of ‘num’ inside loller should always be the same as in  
original continuation? Should I remove the analogous assignment from the  
loop in “loller” then as expected i never get “back to root” printout,  
since then “loller” always returns to the point after the original  
assignment, and thst is just before the while loop.

Anybody who understand this, please explain. Big thanks in advance.

/Paul W Florczykowski

---

<div class="post-metadata">

**Author:** ![paulf](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/eb9ed0/32.png) [@paulf](https://www.ruby-forum.com/u/paulf)\
**Post date:** [February 3, 2009, 2:50am UTC](https://www.ruby-forum.com/t/continuations/159277/2 "2009-02-03T02:50:34Z")

</div>

Responding to Paul w Florczykowski:

[Disclaimer: I’m certainly not a pro on continuations, but I’ll just  
give it a try. Please bear with me.]

> ```
> # any subsequent calls to 'well' (well.call) should return to THIS POINT
> # callcc { |here| well.call(here) }, w/o assignment works here!!!
> callcc { |here| well.call(here) } #B
> puts "back to root " + i.to_s
> i += 1
> 
> ```
> 
> end

Continuations don’t capture a frozen state but rather a live environment

- you can return to the same continuation and encounter different local  
state each time.

i = 0  
callcc{|cc| puts “assign once”; $cc = cc}  
i += 1  
puts(i)  
$cc.call unless i == 3

So you don’t need to ‘update’ your continuation references in order to  
keep track of changed state (such as the num value inside loller). The  
reason you require the assignment to ‘that’ is because on the initial  
method invocation it will have the ‘wrong’ value - it will transfer back  
to #A, and you have to fix that after the first control transfer back  
into loller via ‘well’ to point to #B instead. (Which is also why you  
get two successive messages from loller before the root messages kick  
in.)

A slightly modified version of your code:

def loller(id, num, that)  
loop do  
puts id.to\_s + " " + num.to\_s  
num += 1  
sleep(0.5)  
callcc { |here| that.call(here) }  
end  
end

i = 0  
well = nil  
while true  
if(well.nil?)  
well = callcc { |there| loller(1,34,there) }  
else  
callcc { |there| well.call(there) }  
end  
puts "back to root " + i.to\_s  
i += 1  
end

Best regards,  
Patrick

---

<div class="post-metadata">

**Author:** ![paulf](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/eb9ed0/32.png) [@paulf](https://www.ruby-forum.com/u/paulf)\
**Post date:** [February 3, 2009, 12:37pm UTC](https://www.ruby-forum.com/t/continuations/159277/3 "2009-02-03T12:37:39Z")

</div>

Paul w Florczykowski wrote:

> Anybody who understand this, please explain. Big thanks in advance.

The way I think of it: firstly

- A closure is an environment in which variables are evaluated and  
stored

Once you ‘get’ closures, then:

- A continuation is a closure plus an execution pointer

Some closure examples I read a while back were not helpful. One I think  
talked about going across a railway crossing, getting run over by a  
train, and then rewinding to before you went across.

Using a continuation, you can rewind to before you went across, but  
you’ll still be dead 🙂

Regards,

Brian.

---

<div class="post-metadata">

**Author:** ![paulf](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/eb9ed0/32.png) [@paulf](https://www.ruby-forum.com/u/paulf)\
**Post date:** [February 3, 2009, 7:04pm UTC](https://www.ruby-forum.com/t/continuations/159277/4 "2009-02-03T19:04:06Z")

</div>

Patrick R. wrote:

> …  
> So you don’t need to ‘update’ your continuation references in order to  
> keep track of changed state (such as the num value inside loller). The  
> reason you require the assignment to ‘that’ is because on the initial  
> method invocation it will have the ‘wrong’ value - it will transfer back  
> to #A, and you have to fix that after the first control transfer back  
> into loller via ‘well’ to point to #B instead. (Which is also why you  
> get two successive messages from loller before the root messages kick  
> in.)  
> …  
> Best regards,  
> Patrick

Appreciate the reply! it actually helped me understand this! Thanks  
again!
