How did iteratees get their names?

I love iteratees as a paradigm for IO, but I am having trouble developing a relationship with the names. Could someone explain their origin? It seems like if iteratees consume things, enumerators produce them, andenumeratees do both that names like Sink, Source, and Transformer or Consumer, Producer, and Transformer might be more relatable choices? Is there some reason apart from convention why these names wouldn't fit the concepts well? -- J. Douglas McClean

Douglas McClean
I love iteratees as a paradigm for IO, but I am having trouble developing a relationship with the names. Could someone explain their origin?
It seems like if iteratees consume things, enumerators produce them, andenumeratees do both that names like Sink, Source, and Transformer or Consumer, Producer, and Transformer might be more relatable choices? Is there some reason apart from convention why these names wouldn't fit the concepts well?
Well, everything in the iteratee concept is an iteratee. An enumerator is itself an iteratee (that usually just isn't fed with input). Hence those clearer names wouldn't really fit. An enumeratee is an iteratee that takes another iteratee and feeds it with input. It might use its own input for that. An enumerator is a special case of that, which ignores its own input. Just like chatter and chattee, employer and employee, there is an iterator (usually as part of an enumerator/ee) and an iteratee. Greets, Ertugrul -- nightmare = unsafePerformIO (getWrongWife >>= sex) http://ertes.de/

Hi, Ertugrul wrote:
Just like chatter and chattee, employer and employee, there is an iterator (usually as part of an enumerator/ee) and an iteratee.
Thanks for the attempt to explain. But I, at least, remain mystified, and I agree with Douglas that the terminology is confusing. Usually, the relationship between word-pairs such as the ones above is pretty obvious, typically implying some kind of subordinate relationship. For example: * employer: the one employing employee: the one employed * tutor: the one teaching, instructing, providing care tutee: the one receiving instruction, care * caller: that which is calling callee: that which is being called And so on. The above would suggest that "iterator" would be something that iterates over something, and that "iteratee" would be (an element of) that being iterated over. However, no such simple relationship seems to emerge from the provided explanation. I also had a look at John Millikin's page on Understanding Iteratees, which is very good: https://john-millikin.com/articles/understanding-iteratees/ But, the intuition that comes across there is: * iteratee: a stream (of sorts) consumer * enumerator: a stream (of sorts) producer * enumeratee: a stream (of sorts) transformer And "iterator" isn't mentioned at all. I might be missing something, but the terminology is hardly crystal clear. Which is a pity! Best, /Henrik -- Henrik Nilsson School of Computer Science The University of Nottingham nhn@cs.nott.ac.uk

Henrik Nilsson
Just like chatter and chattee, employer and employee, there is an iterator (usually as part of an enumerator/ee) and an iteratee.
Thanks for the attempt to explain. But I, at least, remain mystified, and I agree with Douglas that the terminology is confusing.
Usually, the relationship between word-pairs such as the ones above is pretty obvious, typically implying some kind of subordinate relationship. For example:
* employer: the one employing employee: the one employed
* tutor: the one teaching, instructing, providing care tutee: the one receiving instruction, care
* caller: that which is calling callee: that which is being called
And so on.
The above would suggest that "iterator" would be something that iterates over something, and that "iteratee" would be (an element of) that being iterated over.
You are right. In that case it really doesn't make sense. However, one way to make sense of this is that the iteratee is indeed being iterated over. Consider that the iteratee /contains/ the stream. The stream isn't fed from outside, because the enumerator itself is an iteratee and that one creates the stream in the first place.
However, no such simple relationship seems to emerge from the provided explanation.
I also had a look at John Millikin's page on Understanding Iteratees, which is very good:
https://john-millikin.com/articles/understanding-iteratees/
But, the intuition that comes across there is:
* iteratee: a stream (of sorts) consumer
* enumerator: a stream (of sorts) producer
* enumeratee: a stream (of sorts) transformer
And "iterator" isn't mentioned at all.
That's because the iterator isn't part of the system at all. You bring in the iterator from outside. For example a loop reading chunks from a file is an iterator. That iterator is used inside of an enumerator, which is itself an iteratee that transforms another iteratee (in that it handles the Continue state).
I might be missing something, but the terminology is hardly crystal clear. Which is a pity!
That's true, but on the other hand personally I wouldn't know how to improve it without giving a wrong intuition. Coroutines actually capture this kind of composition (where some code interrupts itself to hand control over to some other code) very well. Perhaps it would be better to use terms from that abstraction instead. In fact, iteratees are a special case of coroutines. Greets, Ertugrul -- nightmare = unsafePerformIO (getWrongWife >>= sex) http://ertes.de/

Hi Ertugrul,
Coroutines actually capture this kind of composition (where some code interrupts itself to hand control over to some other code) very well. Perhaps it would be better to use terms from that abstraction instead. In fact, iteratees are a special case of coroutines.
That would seem to make sense, if there is appropriate terminology. And if we are indeed talking about co-routines, i.e. cooperation between peers, routines of equal status, that would in itself suggest that the X-or and X-ee names that imply an asymmetric relationship are somewhat unfortunate choices conveying the wrong intuition. Best, /Henrik -- Henrik Nilsson School of Computer Science The University of Nottingham nhn@cs.nott.ac.uk

Henrik Nilsson
Just like chatter and chattee, employer and employee, there is an iterator (usually as part of an enumerator/ee) and an iteratee.
Thanks for the attempt to explain. But I, at least, remain mystified, and I agree with Douglas that the terminology is confusing.
FWIW, I always thought it was a kind of pun on the iterators in OO-land. There, the iterator is a cursor-like object, and the program controls it to iterate over the input -- typically a collection or similar. Iteratees invert this, the "program" is in the form of an iteratee, and it is being iterated by the input (enumerator). So the iterator is actively controlling a passive (or reactive) input, while the iteratee is reactively processing an active or controlling input. Or something, I'm hardly an authority on this. I hope it makes sense. -k -- If I haven't seen further, it is by standing in the footprints of giants

On 12/7/11 10:21 AM, Henrik Nilsson wrote:
I also had a look at John Millikin's page on Understanding Iteratees, which is very good:
https://john-millikin.com/articles/understanding-iteratees/
But, the intuition that comes across there is:
* iteratee: a stream (of sorts) consumer
* enumerator: a stream (of sorts) producer
* enumeratee: a stream (of sorts) transformer
And "iterator" isn't mentioned at all.
The "iterator" terminology is from the object-oriented world; iteratees are explicitly offered as an alternative to the iterator approach, which is why we don't have iterators. An iterator is something which iterates over a collection--- to produce the elements in that collection. In the iterator approach the sink (the for-loop) is in charge and it pulls the data from the source (the iterator). The problem, of course, is that the source never knows whether the sink will pull the next element or not, so it never knows when it's done. An iteratee is also something which iterates over a collection--- to consume the elements in that collection. In the iteratee approach the source (the enumerator) is in charge and it pushes the data into the sink (the iteratee) until the sink declares that it's had enough! and then the source knows it's done and it can free whatever resources need freeing. So there are actually two issues going on here: one is the source-vs-sink distinction, and the other is the active-vs-passive or push-vs-pull distinction. Since we have two binary features, we can have them be aligned in parallel or in opposition (which one is which is irrelevant). iterator-style --- source : sink :: passive : active iterator = passive source for-loop = active sink (pull) iteratee-style --- source : sink :: active : passive enumerator = active source (push) iteratee = passive sink The "enumeratee" terminology comes from a pun about something which is both an "enumerat(or)" and also an "(iterat)ee". However, it would have been much clearer IMO if instead we had used this terminology retroactively as a name for the for-loop or other active sink in the iterator style. If this had been done, then we could use the following analysis: iterat- = passive enumerat- = active -or = source -ee = sink Which preserves the analogy you want. "Employers" are the source of employment, and "employees" are the sinks/consumers of employment. To make sense of the active-vs-passive distinction, rather than thinking about the employers as the ones being active (i.e., thinking of employment as the commodity), we could instead choose to frame our discourse around "workers" as the source of work (i.e., thinking of labor as the commodity). In this case we would expect "workees" to be the consumers of work/labor; but, alas, we have no word for rendering employers as passive participants in the world of economic transactions. -- Live well, ~wren
participants (5)
-
Douglas McClean
-
Ertugrul Söylemez
-
Henrik Nilsson
-
Ketil Malde
-
wren ng thornton