On 8/19/04, [EMAIL PROTECTED] (Luke Palmer) wrote:
>David Green writes:
> > Hang on -- should we be saying "for each $foo" or "for $foo.each"
> > anyway? We don't say "for @foo.each"; the iteration is implicit. So
> > I'm thinking it should be "for $foo" or "while next $foo".
>
>Well, C<for $foo> gives you a one-iteration loop.
Oops, I meant $foo to be some iterable object... but yes, that conflicts
with referring to the object itself (such as a plain scalar... although
I guess anything without an explicit iterator method could simply
"iterate" by returning itself once).
But I was confusing myself there anyway. I was thinking that "for"
would somehow have to call the iterator implicitly because if the
iterating method just returned the next value in scalar context and all
values in list context, then "for $object" would pull everything (all
the $object-s flattened) instead of pulling each subsequent $object one
at a time (i.e. lazily).
Then I thought that maybe "for" doesn't need to work lazily (except that
the conveniently just-posted Synopsis 4 confirms that it is supposed to
be lazy). Or maybe "for" is only "as lazy as is reasonable", meaning if
it knows how (e.g. if you're using an array or filehandle, which have
known ways to meander through lazily), or if you write a really fancy
iterator for your object that can handle laziness.
If your iterator (in list context) just returns everything at once, then
"for" will effectively flatten the list because there's nothing else it
can do. (If you need one-at-a-time behaviour, use a while loop!)
Hm... but it still seems it would be good if "for" could know what the
iterator method is for any given object, so that it could call the
(single) iterator one at a time and get through any sequence as lazily
as possible.
>Which implies that iterators can behave as arrays. Then you get to
>weird questions like what:
> $foo[-1]
>Does. Iterate to the end and return that? The array abstraction
>doesn't work well for iterators, so perhaps that's not the best way to
>go.
Yeah... my instinct would be that if you want that much array-like
behaviour, then tie your object to or inherit it from an Array.
>I'm personally a fan of "every" as well as renaming Ruby's "each" to
>something else.
I was also warming up to "sequel", but it's kind of long to type.
OK, using "next" is a problem because of things like:
$foo='LINE'; next $foo;
but what if labels had to be stored in special "label objects" instead
of plain strings? Well, that could still cause problems if you ever
wanted to iterate over some label names, I guess. (Don't ask me why
you'd want to do that...)
Anyway, now that everything's a closure, isn't labelling a block a lot
like naming the block/closure/sub? (Probably not... =P) Hm -- you can
also label a statement on its own... I forgot about that because I don't
think I've ever actually seen Perl code that does that. (You can't
'next' to a statement anyway, only to a labelled block.)
- David "starting to confuse myself again" Green