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