On Thu, Aug 19, 2004 at 10:53:06AM -0500, Jonathan Scott Duff wrote: : I like "each" best though. Why exactly can't it work?
It could be made to work. The sources of cognitive interference are: 1. Perl 5's each(%hash) function, which is probably not a problem. 2. Ruby's array.each {|x| print x } construct, which probably ought to be spelled differently anyway. 3. English's "each", which doesn't work so well in "while each $IN". It's hard to come up with an English word that means "next" in scalar context but "all" in list context. So I lean toward punctuation, and since <> is historical, I like <$IN> and $IN.<> for that. But if I had to pick a good generic word that doesn't commit, I'd pick .read as a shortened form of Perl 5's .readline. (Leaving aside the conflict with the current read() function, which *might* be resolvable with MMD.) If we try to set up a table, we get something like: next as scalar all as list ============== =========== $iter $iter.read $iter.read @array @array.shift @array $array $array.shift @$array $array[] %hash %hash.each %hash .keys .values .pairs .kv $hash $hash.each %$hash .keys .values .pairs .kv This table shows us a number of bogusoidal facts. .read and .shift are destructive. Nothing else is. But .read and .shift are not synonymous in list context. %hash.each doesn't actually return a scalar if we follow Perl 5, which we probably aren't. %hash probably means %hash.pairs in list context. Arguably .keys, .values, .pairs, and .kv should all autoiterate in scalar context, which should replace .each entirely. @array should respond to .pairs and .kv, pretending the implicit array indexes are hash keys. There is no non-destructive scalar iterator for arrays except a C<for>, which makes me wonder if there is a Rubyesque @array.for:{ dostuff }. So let's rewrite the table (assuming that all the hash methods are just variants of .values), where N and D are non-destructing and destructive: next D next N all D all N ====== ====== ===== ===== $iter $iter.read ?1 $iter.read ?2 @array @array.shift @array.for @array.splice @array $array $array.shift $array.for $array.splice @$array %hash ?3 %hash.values ?4 %hash.values $hash ?3 $hash.values ?4 $hash.values Hmm. Ignore ?1 and ?2, since it's not clear that iterators can be read non-destructively. It looks like most of the problem is that we're not consistent in how to destructively read something in a context sensitive manner. And I don't really like .read anyway. Without necessarily deprecating .shift or .splice, how about a table that looks like this: next D next N all D all N ====== ====== ===== ===== $iter $iter.pull ?1 $iter.pull ?2 @array @array.pull @array.values @array.pull @array $array $array.pull $array.values $array.pull @$array %hash %hash.pull %hash.values @array.pull %hash.values $hash $hash.pull $hash.values @array.pull $hash.values After all, a pull is the other end of a push. Larry