In Haskell, Iteratee based I/O seems very attractive. Iteratees are a composable, safe, fast ways of doing I/O inspired by the 'fold' a.k.a. 'reduce' function in functional languages. Basically, if you have a traversal the idea is to encapsulate the traversal state into a so-called "enumerator" who calls the "iteratee" which is in turn a function either returning a value or a request for more data along with a continuation for the enumerator to call. So only the enumerator knows the state of the traversal while the iteratee knows what to do with the data and builds values out of it. The nice thing about it is that iteratees are automatically composable, where output of one iteratee is fed to another to make a bigger one.
So, two questions:
First of all, realize that Haskell's "Lazy IO" is kind of a hack that breaks purity in a limited way to allow I/O to occur on demand as data is consumed lazily. This is business as usual in an impure language, and lazy sequences can create the same problem anywhere. So if you're doing something like, say, exposing an IEnumerable
interface to a file and reading it incrementally as the sequence is enumerated, this isn't really any different.
Second, iteratees and enumerators can also be composed into what are called (in somewhat clumsy fashion) enumeratees. At this point you have something being fed sequential data, producing incremental results as they're ready, and feeding those results to something else. This is basically a variety of stream processor, a concept which probably predates both Haskell and C# by a considerable margin.
Third, iteratees are an encapsulation of abstracted behavior, with their internal workings hidden. This is arguably more in keeping with OO principles than with ML-style functional programming, at least in the sense of "OO principles" that are espoused by the people who yell at you for using getters and setters and think control flow should be implemented via polymorphism.
Given the above, I'd say that the iteratee concept would fit just fine in C#, and would be most naturally implemented as a sort of inverted equivalent of IEnumerable
, with compositional data-flow objects and a "push" interface rather than the standard LINQ's "pull" style.
If I understand what you're describing, it sounds an awful lot like the Reactive Extensions:
http://channel9.msdn.com/Tags/reactive+extensions
Erik Meijer explains how IObservable is the mathematical dual of IEnumerable here:
http://channel9.msdn.com/Shows/Going+Deep/Expert-to-Expert-Brian-Beckman-and-Erik-Meijer-Inside-the-NET-Reactive-Framework-Rx
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With