Intra-context suspension and resume control device.
Class Continuation( callable )
callable | A function or any callable item. |
This instances of this class can be used to execute some code that can be interrupted at any time and resumed later from the point they were interrupted.
The function or other callable item set as the parameter in the constructor of this class will receive a special copy of the instance when this instance is called as a functor. For example:
function callable( cont ) > cont.toString() end c = Continuation( callable ) c() // will call callable( c )
The special instance which is passed to the callable item is itself a functor. Calling it causes immediate suspension and return to the original frame where the continuation instance was first called. An optional value can be returned to the caller by passing it as a parameter of the continuation instance.
For example; the following code returns to the continuation first caller if the random number matches a dividend of a "secret" number.
c = Continuation( { c, secret => while true r = random( 2, secret ) if secret % r == 0 c(r) // return "r" to our caller end end }) > "A random factor of 136: ", c(136)
Other than returning immediately to the first caller of the continuation, the current state of the called sequence is recorded and restored when subsequent calls are performed. The following code returns the position where a given element is found in an array:
finder = Continuation( { c, elem, array => for n in [0: array.len()] if array[n] == elem: c(n) end }) pos = finder(10, [1,"a",10,5,10] ) while pos >= 0 > "Found a '10' at pos ", pos pos = finder() end
Parameters passed in subsequent calls are returned inside the continuation function. For example, the following code adds a parameter that is passed from the caller to the callee and then displayed:
finder = Continuation( { c, elem, array => for n in [0: array.len()] if array[n] == elem > "Found ", c(n), " elements." end end }) pos = finder(10, [1,"a",10,5,10] ) count = 0 while pos >= 0 > "Found a '10' at pos ", pos pos = finder(++count) end
Note: It is not possible to use continuations in atomic calls; for/in generators are called as atomically, so it's not possible to use continuations as generators in for/in loops. Use standard b while loops instead.
Separate continuations calling the same functions have a completely different state.
Also, the Continuation.reset method clears any previously existing state of a continuation, so that it can be called anew again without the need to recreate it.
Methods | |
__call | Enters into or exit from a continuation. |
complete | Indicates if the continuation has been completely executed or not. |
reset | Clears the continuation state. |
Enters into or exit from a continuation.
Continuation.__call( ... )
... | parameters passed to the callable stored in the instance, or to the return value. |
Return | The parameter passed to this method from inside the continuation. |
For the complete usage pattern, see the Continuation class.
Indicates if the continuation has been completely executed or not.
Continuation.complete()
Return | True if the continuation code has exited through any mean except calling the continuation. |
When the code inside the continuation calls the continuation, it means it has more operations to perform; the calling code may then decide to call the continuation to let it continue, or to reset it, or just to discard it.
Clears the continuation state.
Continuation.reset()
Allows to recycle a continuation after it is terminated, or at any moment. This must be called when the continuation has returned the control to its caller: it has no effect otherwise.