Dmitri, first of all thanks for the detailed comments.
I have not yet read all of the latest postings but hope that I am not creating too much confusion.
Here are some design thoughts from my side.
You may find the first paragraphs destructive, but please read on. It gets more constructive below.
The distinction between directed and undirected coroutines is not very well established in the community.
I can only find the mentioned reference in the Wiki2, which is not the same as wikipedia.
It looks to be more like an ad-hoc classification of somebody than established terminology.
Personally, I have never heard this before.
All coroutine packages that I have ever seen had something like a directed TRANSFER.
Limiting the target of TRANSFER leads to special programming patterns that are application specific.
Removing the directed transfer at all because it can be used erroneously seems quite radical to me.
It is much like removing recursion because it can lead to stack overflow.
This is probably the reason why I couldn't get started with the Co_ package easily.
Saying that coroutines must be stacked like subroutines is also quite radical.
In general, they may not be stacked like subroutines. There is, however, one aspect that is
like subroutine stacking at least in many cases and this is the starting of coroutines.
Every coroutine (except main) has exactly one coroutine that started it and usually, but not necessarily,
the starting coroutine survives the started coroutine.
I will come back to this below.
A special problem arises with a RETURN from a coroutine. As I have mentioned earlier in the center forum,
it was not clear to me if the current definition is appropriate. The current definition allows a RETURN
and means a transfer to the caller (from), if the caller still exists, otherwise to main. In most cases the caller will
exist but it is of course possible to construct cases where it does not exist any more because it has already returned.
Many coroutine packages don't allow a RETURN at all but require an explicit transfer at the end of the coroutine.
This would also be easy to implement. Allowing the RETURN has the advantage that it saves an extra statement
at the end of a coroutine if the default behavior fits with the coroutine's need. Disallowing the RETURN has the
advantage that it makes it explicit which transfer is done and it avoids any discussion about the semantics.
Anyway, the more I think about it the less I like the current implementation.
If a special programming pattern requires that the starting coroutine, let's call it "parent", is the same as the
transferring coroutine this could be implemented inside the coroutine by introducing a local "parent" variable
initialized as parent := this.from at the beginning of the coroutine. After any transfer an ASSERT(parent = this.from)
can be inserted. This pattern could be simplified further by introducing a "parent" field in
the Coroutine base type. The overhead is very small and it does not have any overhead in a
Transfer operation. Then there is at least a simple possibility for runtime checking some patterns.
Furthermore there could also be a wrapper around the Transfer operation (Yield?) that has this ASSERT included.
Such a special Transfer can be done in the application code or it could be added to Coroutines.
Similarly, a Transfer wrapper can be used in the starting coroutine (Generate?).
It adds ASSERT(current.from = target) after the Transfer(target). Generate and Yield would be Transfer
wrappers for the iterator pattern.
If a "parent" field is introduced in the Coroutine base type this would lend itself as a better target for
RETURN. The semantics would be that RETURN transfers to parent and if parent does no longer exist,
it traps, and thereby eventually transfers to main.
Or, more traditionally, RETURN is not allowed at all.
My latest update introduces the mentioned features (parent, Iterator, Task).
Some details are also changed e.g. from renamed to source and Pause renamed to Sleep.
RETURN now transfers to parent.
You may want to look into the latest build at
http://blackboxframework.org/unstable/i ... a1.833.zip.
The diffs are here:
https://redmine.blackboxframework.org/p ... e1ac8bf0c0.
- Josef