Question

Okay I'm just about ready to give up on this.

I would like to save the state of a continuation (done using shift). However, the caveat is that the code AFTER the reset should not be executed. Consider the continuation being executed by worker thread, and should no longer be processed. The continuation is saved in a global list of continuations that can be resumed, and everything else after it is disregarded and should not execute.

The worker thread must survive (it cannot be aborted, or destroyed requiring the spinning up of a new thread).

reset {
  shift {
    (cont:Unit=>Unit) =>
      println(1)
      suspend() // how would I implement something like this?
      cont()
  }

  println(3)
}

println(2)

should yield

1

resuming the continuation should then yield

3
2

At the moment this does not seem possible at all, since the continuation is limited to the scope of the reset. But I figured I'll give StackOverflow one crack at it.


Edit: Basically... (maybe I should have put this earlier) I want to call a method, and suspend execution until it is ready to give me a result, and I want to achieve this over an evented loop, not thread synchronization.

Was it helpful?

Solution

I'm not sure, whether this is applicable to your situation, but here is example of how to mix multiple resets:

  type Proc = Unit => Unit

  val resume = reset {
    shift { k1: Proc =>
      reset {
        shift { k2: Proc =>
          println(1)
          () => k2(); k1() 
        }        
        println(3)
      }
    }
    println(2)
  }
  // 1

  resume()
  // 3
  // 2

Update: And here is how to use this with methods:

  def f(): Unit @cpsParam[Unit, () => Unit] = {
    println(0)

    shift { k1: Proc =>
      reset {
        shift { k2: Proc =>
          println(1)
          () => k2(); k1()
        }        
        println(2)
      }
    }

    println(3)
  }

  val continue = reset {
    println(-1)
    f()
    println(4)
  }

  println("...")

  continue()

Prints:

-1
0
1
...
2
3
4

And here is what to do if you don't want to suspend everything after call to f until the ending of reset:

  reset {
    println(-1)
    shift { k: Proc =>
      reset{f()}()
      k()
    }
    println(4)
  }

  println("...")

Prints:

-1
0
1
2
3
4
...
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top