David A. Black wrote:

>>
>> a.select.with_index { |x,i| x%2 == 1 and i >= 2 }  # => [3,5]
>>
>> This, I think, is a pretty convincing reason for select to return an 
>> Enumerator.
> 
> You're right that I knew that, though I hadn't factored it in,
> so you're even more right to remind me :-)
> 
> But I'm not sure it's enough of a reason. For one thing, I can't seem
> to think of any case other than with_index where chaining select to
> anything makes sense. 

The proposed with_memo function would presumably work in place of, or in 
addition to with_index here.

I believe that's because with_index is one of
> the few methods that Enumerators have that don't come from Enumerable,
> so it's designed to be sort of additive, whereas most of the others
> just plain "win":
> 
>   a.select.map     # might as well be a.map
>   a.select.inject  # might as well be a.inject
>   etc.

It seems like these ought to raise an exception, doesn't it?

I do think that enumerators are a beautiful thing when returned by 
iterators that just iterate (for example: file.lines.with_index).  But, 
as you point out, they get weird when used with iterators that map or 
filter.  I don't think we fully grok these yet. Maybe Matz has a plan 
here.  Or maybe the best thing would be to only allow straight iterators 
to return Enumerators.

Actually, what would probably solve the problem is to modify methods 
like select and map to accept a lambda as an argument.  When called with 
a lambda and no block they'd return an Enumerator that would use that 
lambda as its block.  The difference from invoking select or map with a 
block is in the deferred computation.  Using an enumerator that way 
allows infinite sequences, for example.

	David Flanagan