    [NAME]
    ALL.module.core.coroutine

    [TITLE]
    Coroutine and Generator

    [DESCRIPTION]

    Coroutine is a generic data type that can turn a routine into coroutine or generator.
    It has the following type form,

       1  coroutine<@RESUME,@YIELD>

    where @RESUME is the type holder for the type that can be passed to its resume() method,
    and @YIELD is the type holder for the type that can be passed to its yeild() method.

    To create a coroutine that can be resume with a integer value, and yield a string value,
    the coroutine type should be created in following way,

       1  co = coroutine<int,string>()

    The routine that will be used to create the coroutine need to be defined with the first
    parameter named self with the coroutine type,

       1  routine Test( self :coroutine<int,string>, initpar : string )
       2  {
       3      for( i = 1 : 5 ) io.writeln( self.yield( initpar + 'abc' ) )
       4  }

    In such routine, self.yield() can be used yield the control of the execution and pass
    its parameter to the caller of self.yield() or self.resume().

    Then the coroutine can be started by,

       1  a = co.start( Test, 'test' )

    which will start the coroutine and execute it until the first yield (if any). It will
    return the first yielded value.

    The coroutie can be resumed using,

       1  a = co.resume( 100 )

    The parameter passed to resume() will become the returned value of yield(). And the
    parameter passed to yield() will become the returned value of resume().

    The status of coroutine can be checked with,

       1  status = co.status()

    A complete example,

       1  load coroutine
       2
       3  routine Test( self :coroutine<int,string>, par : int )
       4  {
       5      for( i = 1 : 5 ) io.writeln( i, self.yield( 'index_' + (string) (par*i) ) )
       6      return 'done'
       7  }
       8
       9  co = coroutine<int,string>()
      10
      11  io.writeln( co )
      12
      13  a = co.start( Test, 100 )
      14  io.writeln( a )
      15
      16  for( i = 1 : 6 ) io.writeln( co.resume( 100*i ), co.status() )