ad 1: I had Next as a function as you suggested in an earlier version. When I applied it to the SameFringe problemRobert wrote:Regarding Iterators:
1 - Would it be simpler for client code if the signature of Next was a function with a BOOLEAN return value? TRUE would mean the status was 'suspended', FALSE would mean 'returned'. Other statuses are, I think, impossible?
2 - It is possible (correct me if I am wrong) to call Coroutines.Transfer with an Iterator. I suspect that 99% of the time this would be done by accident, and 100% of the time it would lead to hard to read and understand code. So I suggest adding a documented TRAP to prevent this.
Of course it would still be called internally by Yield & Next.
it turned out to be very dangerous because it is a function with a side effect. If called twice in an expression it modifies the state,
when not called due to short-cut evaluation it accidentally did not modify the state, etc.
It took me hours to recognize my stupid mistake.
Combining Next and something like HasNext is not a good idea, I am convinced.
An iterator subclass can introduce its own rule for detecting the end of the iteration if checking the state is unwanted.
It could, for example, return NIL at the end or set its own flag "hasNext", etc.
ad 2: Calling Coroutines.Transfer(iterator) instead of iterator.Next() is possible indeed. But there are already checks in place that
trap if called in a way that violates the semantics of iterators.
Besides that, it is hard to imagine that Coroutines.Transfer is called accidentally.
It is more likely to appear in tests of the robustness of the Coroutines module.
Regarding the docu: it would be easy to insert a link to the coroutine examples (ObxCoroutines) in the docu of module Coroutines.
- Josef