np

coroutine (lib)

Description

The coroutine library provides a facility for simple, single-threaded concurrency.

Library Functions

.create( ƒ ) → coroutine

Takes a function ƒ and turns it into a coroutine.

-- make a coroutine
new c = coroutine.create{ | => #hello }
-- launch the coroutine
print( c:receive() )
true hello

.send( result ) → [inboundArgs]

Yields a result to the called of the coroutine.

-- make a coroutine
new c = coroutine.create{ | 
  new counter = 0
  -- just keep on churning out numbers 
  while(true) {
    counter += 1
    coroutine.send(counter)
    }
  }
-- use the coroutine
print( c:receive() )
print( c:receive() )
print( c:receive() )
true 1
true 2
true 3

.wrap( ƒ ) → wrapperFunction

Creates a coroutine from ƒ and returns a function that, when called, resumes the coroutine as if :receive() had been used. Once the coroutine is done, it ceases to return values.

-- make a coroutine
new c = coroutine.wrap{ | 
  coroutine.send( #hello )
  }
-- use the coroutine
print( 1 c() )
print( 2 c() )
1 hello
2

Coroutine Behaviors

:receive( [args] ) → status, result

When a coroutine is created, it is in a suspended state. To actually query the coroutine for data, the :receive() event is invoked. You can use arguments to send data to the coroutine. If the coroutine has not been executed yet, those arguments are sent as initial function parameters - during later calls these arguments are instead returned by the coroutine.send() call.

-- make a new coroutine
new c = coroutine.create{ | coroutine.send(#hello) }
-- launch the coroutine
print( #Status c:status() #Run c:receive() )
Status new Run true hello

:status( ) → statusString

A coroutine can be in one of four states: new for recently created coroutines that have not yet been called upon, waiting indicates that the coroutine has already been executed at least once and is currently standing by to be called, running for a coroutine that is being run right now, and finally done for coroutines that have completed execution and cannot be resumed.

-- make a new coroutine
new c = coroutine.create{ | coroutine.send(#hello) }
-- launch the coroutine
print( c:status() c:receive() )
print( c:status() c:receive() )
print( c:status() c:receive() )
new true hello
waiting true
done false cannot resume dead coroutine