launch(f, ...)
invokes <f> in a coroutine with the specified arguments
f = spy.new ->
  _, is_main = coroutine.running!
  assert.is_false is_main
dispatch.launch f, 1, nil, 'three'
assert.spy(f).was_called_with 1, nil, 'three'
(when <f> starts correctly)
returns true, the coroutine status, and the coroutine
status, co_status, co = dispatch.launch -> nil
assert.is_true status
assert.equals 'dead', co_status
assert.equals 'dead', coroutine.status(co)
 
(when <f> errors upon start)
returns false, the error message and the coroutine
status, err, co = dispatch.launch -> error 'foo'
assert.is_false status
assert.equals 'foo', err
assert.equals 'dead', coroutine.status(co)
 
 
wait()
yields until resumed using resume() on the parked handle
handle = dispatch.park 'test'
done = false
dispatch.launch ->
  dispatch.wait handle
  done = true
assert.is_false done
dispatch.resume handle
assert.is_true done
returns any parameters passed to resume()
handle = dispatch.park 'test'
local res
dispatch.launch ->
  res = { dispatch.wait handle }
dispatch.resume handle, 1, nil, 'three', nil
assert.same { 1, nil, 'three', nil }, res
raises an error when resumed with resume_with_error()
handle = dispatch.park 'test'
local err
dispatch.launch ->
  status, err = pcall dispatch.wait, handle
  assert.is_false status
dispatch.resume_with_error handle, 'blargh!'
assert.includes err, 'blargh!'
 
resume()
propagates any error occurring during resuming
handle = dispatch.park 'test'
dispatch.launch ->
  dispatch.wait handle
  error 'boom'
assert.raises 'boom', -> dispatch.resume handle
(when nothing is yet waiting on the parking)
      it 'blocks until released by a wait', (done) ->
howl_async ->
  handle = dispatch.park 'out-of-order'
  launched, status = dispatch.launch -> dispatch.resume handle, 'resume-now!'
  assert.is_true launched
  assert.equals "suspended", status
  launched, status = dispatch.launch ->
    assert.equals 'resume-now!', dispatch.wait handle
    done!
  assert.is_true launched
  assert.equals "dead", status