"Robert Klemme" <bob.news / gmx.net> writes:

> 1. One thread's complete state is cloned and resumed in another thread
> context.  That means effectively that on thread disappears.  And suddenly
> you would have to solve all kinds of synchronization problems you weren't
> expecting: assume, you use an instance X in one thread that is thread local

[cut]

>
> 2. The invocation of the continuation makes the continuation's original
> thread stop and resume the continuation.  This will lead to unexpected
> context switches and all kinds of strange behavior.  And what happens to the
> calling thread?  Where does execution resume?  Is the call suddenly
> asynchronous?  That would not fit well with the rest of Ruby since all

[cut]

> In short: I don't see how continuations and threads mix well.
>
> Regards
>
>     robert

Hi,

I find your reply interesting, but am not sure whether you are saying
that continuations and threads do not mix well conceptually or as they
are currently implemented in current official ruby implementation.

Conceptually, I do not find any issue in mixing continuations and
threads. They are distinctly separate concepts. Continuations saves
the execution state at that point. A possible implementation would
probably save the control and binding stacks as what Allergo CL does:

"The control stack maintains the function evaluation state including
lexical bindings. The binding stack records the dynamic bindings of
special variables." (http://tinyurl.com/2hgxw)

Meanwhile, threads are simply streams-of-executions. Resuming a
continuation, then, should be just-another-thing-to-execute. And one
can adopt Scheme's semantic in continuation resumption, that is to
"abandon whatever continuation is in effect ... and will instead use
the continuation that was in effect when the [continuation object was
created]" (http://tinyurl.com/2assv).

So, to address the concerns you raised above:

Concern #1. I certainly agree this is a valid concern. However, I am
   also a proponent of responsible programmer. Thus, I see that the
   responsibility to mix threads and continuations should lie on the
   programmers. The programmers should know what he is doing. I think
   it is reasonable to expect at least this much responsibility from
   the programmer ("enabling" -- http://tinyurl.com/33x57). In any
   case, this concern does not introduce any new responsibility to
   programmers coding non-trivial multi-threaded program: be careful
   when sharing common resources.

Concern #2. The thread that creates the continuation objects need not
   stop, in fact there is no reason for it to stop. The calling thread
   should just resume the continuation at the resumption point, which
   in ruby is the next statement after the callcc{} statement.

So, running the following code (won't run with current official ruby
implementation):

Thread.new { 
  Thread.current[:id] = 1
  puts "#{Thread.current[:id]} A"
  callcc{|c|
    puts "#{Thread.current[:id]} B"
    Thread.new { 
      Thread.current[:id] = 2; 
      c.call
    }
    puts "#{Thread.current[:id]} C"
  }
  puts "#{Thread.current[:id]} D"
}

would result in (may vary depending on thread scheduling):

1 A
1 B
1 C
1 D
2 D

As Eric Hodel pointed out elsewhere in this posting thread, the
problem lies in the current implementation: continuations are
implemented in terms of threads. Thus, they are no longer distinct
entities and, apparently, one of the consequence is that you can't
call continuations from across threads. It will also brings out other
ugly things mentioned in your concern #2. So, apparently, what you
were saying are wrt current ruby implementation.

WRT my original problem that would have benefited from a continuation
that is callable across threads, I have found that Eric Hodel's
suggestion works acceptably.


Thank you,
YS.