opinions on standard iterations?

A

Average_Joe

Hello Newsgroup.

Just soliciting some general opinions.

What would you say is the most sexy, easy to use iterator?

My favorite is to return an object supporting a next() method, (when next()
returns references or lists.) or a getline() method for lines of text. Boring,
but effective.

A close second is to return a code reference:

$code = someFunction();
while( $entry = $code->() ){

}

Easy, uncluttered, simple to do. $code->() can accept arguments if needed,
returning hashes and lists are sane.

I've been thinking about overloading <> so it becomes:

This is listed as "iteration" in overload, I'm left with the notion that it's
supposed to be the standard approach, yet I've never seen it in use for
returning references and lists.

while($entry = <$object>){
# huh?
}

This looks "dirty" to me, except maybe if $entry is plain-text, but where
$entry is a reference to something just seems to weird. One nice thing, I guess
is that you can have it both ways. <$object> OR $object->next() are the same
method.

One quirk, is that if next() is supposed to return a list. Like:

while( @record = <$object>) { ... }

I suppose you could do that, but one would think it should return ALL the
records, if each record is a list, it's kind of confusing.

What about:

while($object){
++$object; # The "iterator".
%rec = %{$object}; # The current value.
$rec = ${$object}; # Same thing.
}

Does that seem sane? To me it seems "more sane", except that you can't always
do --$object (Like if $object were reading from standard input)

Also seems too involved, have to implement 4 different functions instead
of a single 'next()' (and you have to keep track of a "current entry")

Finally, (more serious question I guess) what do you do about callbacks?

Say you use a module that uses a collector style callback. Maybe it performs a
search or something and calls your code reference for each hit.

You wanted to use it as part of your module, but you want your module to return
an iterator. How would you create a callback that can exit and then return
where it left off? Short of altering the module, the only way I can think of is
to build a whole list or use some sort of thread/fork.

Opinions?

Jamie
 
P

Paul Lalli

Average_Joe said:
Just soliciting some general opinions.

What would you say is the most sexy, easy to use iterator?

Joe, have a look at Eric Roode's just-released Iterator module now
available on CPAN. It's styled heavily after MJD's concept of
iterators that he's been lecturing about in talks and his new Higher
Order Perl book. I've only looked at it briefly, but I'm rather
impressed with both the flexibility and structure that Mr. Roode built
in.

http://search.cpan.org/~roode/Iterator-0.01/Iterator.pm

Paul Lalli
 
T

Tassilo v. Parseval

Also sprach Average_Joe:
Hmm basically a variant of $object->get_next_whatever() with a more strict
approach in dealing with the 'eof' condition? (just returning an empty list
won't do) complemented by a framework of iterator utilities. It is impressive
looking. I like the idea.

It's nice to have it throw an exception on repeat calls to prevent accidental
infinate loops I guess. OTOH, it does seem kinda heavy.

That is the one bit I don't like about the implementation either. MJD's
book clearly states that the actual challenge with iterators is the
semipredicate problem, that is: signalling the end of the iteration in a
generic way that doesn't limit the range of values an iterator may
return.

Mind you, in code like this:

my $iter = Iterator->new(
sub {
...
if (done) {
# signal exhaustion for
# the very oject to be
# created in this statement:
# so $iter cannot yet be used
Iterator::is_done();
}
}
);

Eric's approach is the most elegant one interface-wise. I'd probably
have done it with a special return value such as $Iterator::EOF being an
object with special properties. But strictly speaking, that would not
solve the semipredicate problem.
Problem is, there are a dozen or more get_next() type method names out there,
if you had some code that expected an "object that supplies a
get_next_record()" but want to feed it something that has a fetch_row() method,
you'd need a wrapper.

That is always the case. Note that other languages would impose certain
requirements on such an object. In Java its class would almost certainly
have to implement an Interface listing the get_text() method.
As ugly as they are <$object> does solve this problem, since <> is a standard
operation and it comes with perl, doesn't involve any modules besides the
overload pragma.

What about a tied array that *only* supports SHIFT ?

while($rec = shift(@{$object})) ... # ???

Does that seem totally ugly? Couldn't really return a list that
way though.

It's somewhat counter-intuitiv do have an array that only supports SHIFT
and is this crippled with respect to the other array operators normally
found.

Not being able to return a list is however a limitation of the
overloaded ' said:
Wonder how likely Eric Roode's Iterator package is to make it into
the core modules?

My prediction is: Not ever. The official policy is now to only add
modules to the core when these modules aid in building other modules.
The Iterator::* modules recently uploaded are all pure Perl and
therefore should be a breeze to install almost anywhere.

Tassilo
 
A

Arne Ruhnau

Tassilo said:
Also sprach Average_Joe:




That is the one bit I don't like about the implementation either. MJD's
book clearly states that the actual challenge with iterators is the
semipredicate problem, that is: signalling the end of the iteration in a
generic way that doesn't limit the range of values an iterator may
return.

The only argument MJD has, as I can recall, to not limit the return values
of iterators to array-references, is that this could be inconvenient for
the caller if the iterator's value is just a single scalar.
Or was there anything else that could justify more work than necessary to
interface an Iterator?

Arne Ruhnau
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,577
Members
45,054
Latest member
LucyCarper

Latest Threads

Top