Yukihiro Matsumoto wrote:
> 
> |I should say, however, that I don't care for the name 'butfirst'.
> 
> It's a traditional name (but slightly different behavior) inherited
> from Logo.  In Logo, butfirst is cdr in Lisp, which returns given list
> with its first element removed.

Well tradition helps, but I think I'd still prefer another name.

> |I've got three alternatives to propose:
> |
> |1) How about 'skip' (or 'discard') instead, which would nicely support 
> |its use as an enumerator like this:
> |
> |     c.skip(n).map {|x|...}  # map all but the first n
> |
> |If you like this, I'd also propose 'only' (or 'limit'):
> |
> |     c.only(n).map { |x| ...} # iterates no more than n elements from c
> 
> We already have #first, that works in reverse of #butfirst.  I am not
> sure skip/only pair is better, especially when #only would work same
> as #first.

#first is not the reverse of #butfirst.  first returns an array but 
butfirst is an iterator and just returns the collection it is called on.

I think I share David Black's concern.  He wrote:

> Especially with the magic enumerators, it's going to be hard to tell
> what's going on if the method names are too subtle.

Some enumerable methods return arrays, some return enumerators, and it 
is beginning to get confusing.  I made a little table of the methods I'm 
discussing here:

Method	       block		 with block         without block
-------------------------------------------------------------------
butfirst      iterates        returns collection   returns enumerator
first	      not allowed     not allowed          returns array
take	      selects	      returns array        returns array
drop	      selects	      returns array        returns array
grep	      iterates        returns array        returns array
select        selects         returns array        returns enumerator
find          selects         returns element      returns enumerator

I have a couple of related thoughts about this.

First, are you sure that you want methods like find and select to return 
enumerators when called without a block?  Since the block is used for 
filtering elements rather than enumerating them, I don't really see the 
use case here.  I think I'd prefer methods like these to require a 
block.  If someone really wants to create an enumerator from them, they 
can use enum_for, of course. I'd suggest that only more traditional 
iterators should return enumerators when called without a block.

Second, I wonder if it is possible to unify Array and Enumerator so that 
one behaves like the other.  Then we could treat all methods as if they 
returned an array or an enumerator.  If we add next and rewind methods 
to Array (which I think would be easy) then we can treat the return 
value of take, drop, select, reject, etc. as an enumerator.

But an even nicer thing would be if Enumerators could act like lazily 
filled arrays.  That is, if I have an enumerator e, but use it like an 
array, it calls to_a on itself internally and then dispatches to the 
array.  With that change, you could modify Enumerable#grep, for example, 
so that it returns an enumerator instead of an array. If you never treat 
the result as an array, to_a never gets called, and you get pipe-like 
behavior that works with unbounded collections.

	David