Throwing exceptions into continuations.

  • Thread starter Christopher Armstrong
  • Start date
C

Christopher Armstrong

Hi all. I'm playing around with Ruby because I like experimenting with
concurrency systems, and found out it has continuations.

I'm going to be calling user-defined code inside of a callcc block,
and the user-defined code will either return a value or raise an
error, and I want that value or error to be passed on to the
continuation.

I can't find any way to throw into the continuation. If there is no
way, can I request that a #throw method be added, or something like
that?

The only alternative I could think of is to have special code on the
calling side of the callcc that will watch the return value to see if
it is a array of two elements, the first being
:special-internal-throw-exception-bit, and if so, throwing the second
element of the array. This isn't what I want, though, especially
because it won't maintain the stack trace from the other side.
 
D

daz

Christopher Armstrong said:
Hi all. I'm playing around with Ruby because I like experimenting with
concurrency systems, and found out it has continuations.

I'm going to be calling user-defined code inside of a callcc block,
and the user-defined code will either return a value or raise an
error, and I want that value or error to be passed on to the
continuation.

I can't find any way to throw into the continuation. If there is no
way, can I request that a #throw method be added, or something like
that?

You're more likely to get a response if you can provide some kind of
starting point (even if its pseudo-code) for questions like this.

Here is an example of one inappropriate guess for your case.
It was difficult to make it this complex because (and I _am_ being
serious), you start with some code and the complicated stuff
often reduces right down.
To others: I know, I can reduce this myself. Resist :)


daz



class UserError < StandardError
def initialize(err)
@err = err
end
end

def user_stuff
rn = rand(15)
if rn > 10
puts "* Raising error #{rn} *"
throw:)event, UserError.new(rn))
else
puts "* Returning value #{rn} *"
end
rn
end

10.times do
cc_ret = callcc do |cont|
rc = catch:)event) do
rc = user_stuff
puts '- no error -'
rc
end
rc
end
puts "cc: #{cc_ret.inspect}"; puts
end


### output ###

* Returning value 6 *
- no error -
cc: 6

* Returning value 8 *
- no error -
cc: 8

* Raising error 12 *
cc: #<UserError: UserError>

* Returning value 0 *
- no error -
cc: 0

* Returning value 2 *
- no error -
cc: 2

* Returning value 5 *
- no error -
cc: 5

* Returning value 10 *
- no error -
cc: 10

* Raising error 12 *
cc: #<UserError: UserError>

* Raising error 13 *
cc: #<UserError: UserError>

* Returning value 6 *
- no error -
cc: 6

##############
 
P

Paul Brannan

Hi all. I'm playing around with Ruby because I like experimenting with
concurrency systems, and found out it has continuations.

I'm going to be calling user-defined code inside of a callcc block,
and the user-defined code will either return a value or raise an
error, and I want that value or error to be passed on to the
continuation.

Is there a reason why you are using continuations for this? Perhaps
some other construct like procs or threads would work better.
I can't find any way to throw into the continuation. If there is no
way, can I request that a #throw method be added, or something like
that?

I'm not entirely sure what you mean by "throw into". Do you want to
cause an exception to occur in the middle of the user-defined code?

There is a Thread#raise, if you want to use a thread. You can stop the
thread if you want it to stop running for a while.
The only alternative I could think of is to have special code on the
calling side of the callcc that will watch the return value to see if
it is a array of two elements, the first being
:special-internal-throw-exception-bit, and if so, throwing the second
element of the array. This isn't what I want, though, especially
because it won't maintain the stack trace from the other side.

You might be interested in what I did here:
http://cvs.sourceforge.net/cgi-bin/...rev=1.17&content-type=text/vnd.viewcvs-markup

There are two continuations: one doing the iterating and one waiting for
the next item from the iteration. The iteration loop is wrapped with a
begin/rescue block, and if I get the exception, it gets re-raised by the
caller with a backtrace that includes both the backtrace of the
iteration block and the backtrace of the code that called #next. Not
perfect, but it gives me all the information I need when I'm debugging.

Paul
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Continuations 3
Continuations 4
Throwing unexpected exceptions 5
Still trying to grok GC & continuations 0
Ruby needs continuations... 25
continuations across fork? 10
Throwing exceptions 10
Continuations stability 0

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,521
Members
44,995
Latest member
PinupduzSap

Latest Threads

Top