Sat Aug 1 18:36:34 CEST 2009
Enumerators are better than cursors because:
- enumeration state is hard to represent
- open/close needs to be handled explicitly
- end-of-stream needs out-of-band value
Ultimately this is about memory management.. You want an enumerator
to make sure that a resource can be freed when the traversal is done.
Encapsulating it in an cursor object makes this difficult to
manage. How to make sure the cursor is finalized?
I'm already running into these kinds of problems:
* Allow for a free() method by adding an `abort' input atom. This
would allow for dynamic data to exist on the stack. (One could
require streams to be always run to the end?)
* Allow for dynamic data by _moving_ it from scheme atoms. Best is
pjrobably to copy.
Is it possible to turn this into genuine `fold' operation, and have
the stack capture as a special case?
Instead of binding the `yield' to the C procedure, it could be
replaced by a generic closure object called from the procedure by
re-entering the interpreter. Basicly what I'm doing at this moment
(always capturing the stack, turning the enumerator into an cursor)
is _against_ the argumentation for enumerators. I only do it to make
it easy to perform memory allocation in C, but it seems to only avoid
the problems in some special cases.
A different question: for recursive invokations of the interpreter,
can the middle C-part of the call stack be spliced out so the Scheme
part can be flattened? Or is it really simpler to keep the current
`rebasing' as is, but wrap the cursors in an enumerator interface that
can guarantee proper resource finalization?
So.. How do these two conflicting stances find a balance? Generators
allow the removal of tree structurs from C code, but the resulting
objects are difficult to manage if they are not allowed to be
finalized. (They work fine for stack-allocated temporary data