> Larry wrote: > > So you can do it any of these ways: > > for <$dance> { > > for $dance.each { > > for each $dance: { > ^ note colon
1- Why is the colon there? Is this some sub-tile syntactical new-ance that I missed in a prior message, or a new thing? 2- Why is the colon necessary? Isn't the "each $dance" just a bassackwards method invocation (as C<close $fh> is to C<$fh.close()>)? > Then there's this approach to auto-iteration: > > my @dance := Iterator.new(@squares); > for @dance { I think this is called "avoiding the question". Now you've converted an Iterator into an iterator masked behind an array, and asked the C<for> keyword to create apparently a "private" iterator to traverse it. That seems like twice as much work for the same output. Also, I have a problem with the notion of the Iterator class being tasked with creation of iterators -- how do you deal with objects (even TIEd arrays) that require magic iterators? Better to ask the class to give you one. (Of course, C<Iterator.new()> could internally ask @squares to provide an iterator, but again that adds a layer for little apparent gain. > Damian Conway wrote: > The presence of a C<yield> automatically makes a subroutine a > coroutine: > > sub fibs { > my ($a, $b) = (0, 1); > loop { > yield $b; > ($a, $b) = ($b, $a+$b); > } > } > > Calling such a coroutine returns an Iterator object with (at least) > the following methods: > > next() # resumes coroutine body until next C<yield> > > next(PARAM_LIST) # resumes coroutine body until next C<yield>, > # rebinding params to the args passed to C<next>. > # PARAM_LIST is the same as the parameter list > # of the coroutine that created the Iterator What's the value of C<next(PARAM_LIST)>? Is this just a shortcut for re-initializing the iterator? How is this going to work when the iterator has opened files or TCP connections based on the parameter list? my $iter = DNS.iterator(".com."); while <$iter> { $iter.next(".com.au.") if not hackable($_); } Furthermore, what's the syntax for including arguments to next in a diamond operator? while <$iter>($a, $b) { ... $a += 2; } > each() # returns a lazy array, each element of which > # is computed on demand by the appropriate > # number of resumptions of the coroutine body What's the difference between a lazy array and an iterator? Is there caching? What about the interrelationships between straight iteration and iteration interrupted by a reset of the parameter list? Or does calling $iter.next(PARAM_LIST) create a new iterator or wipe the cache? How do multiple invocations of each() interact with each other? (E.g., consider parsing a file with block comment delimiters: one loop to read lines, and an inner loop to gobble comments (or append to a delimited string -- same idea). These two have to update the same file pointer, or all is lost.) Some of questions about iterators and stuff: 1- Are iterators now considered a fundamental type? 1a- If so, are they iterators or Iterators? (See 2b1, below) 1b- What value would iterators (small-i) have? Is it a meaningful idea? 2- What is the relationship between iterators and arrays/lists? 2a- Is there an C<Iterator.toArray()> or C<.toList()> method? 2a1- The notion that Iterator.each() returns a lazy array seems a little wierd. Isn't a lazy array just an iterator? Why else have the proposed syntax for Iterator.next(PARAM_LIST)? (Admittedly the PARAM_LIST doesn't have to be a single integer, like an array.) Or is that what a small-i iterator is? 2b- Is there a C<List.iterator()> method? Or some other standard way of iterating lists? 2b1- Are these "primitive" interfaces to iteration, in fact overridable? That is, can I override some "operator"-like method and change the behavior of while <$fh> { print; } 2b2- Is that what C<each> does in scalar context -- returns an iterator? my $iter = each qw(apple banana cherry); my $junk = all qw(apple banana cherry); my $itr2 = each $junk; # Whoops! Wrong thread... 3- What's the difference among an iterator, a coroutine, and a continuation? 3a- Does imposing Damian's iterator-based semantics for coroutines (and, in fact, imposing his definition of "any sub-with-yield == coroutine") cause loss of desirable capability? (Asked in ignorance -- the only coroutines I've ever dealt with were written in assembly language, so I don't really know anything about what they can be used to do.) 3b- Is there a corresponding linkage between continuations and some object, a la coroutine->iterator? 3c- Is there a tie between use of continuations and use of thread or IPC functionality? Is it a prohibitive tie, one way or the other? That is, I've been thinking that "A coroutine is just a continuation." But if "A continuation implies <...>", for example a semaphore or a thread, or some such, then that may be too expensive. (More ignorance on my part, I'm sure.) 3d- Conversely, what happens when continuations, coroutines, or iterators are used in a threaded environment? Will there need to be locking? 4- Given the historical behavior of binding $_ to the actual data in question (thus making it modifiable via $_) what's the correct behavior for iterators? Will they "upvar", or return a ref, or what? How do I write that? sub fibs() { my ($a, $b) = (0, 1); loop { yield $b; ($a, $b) = ($b, $b + $a); } } for <fibs()> { when 13 { $_ = 100; } print "$_\n"; } DWIM? ( ... 5, 8, 13, 100, 113, ... ) > In a scalar context: > > <$fh> # Calls $fh.readline (or maybe that's $fh.next???> I think it's $fh.next. $fh.next calls $fh.readline, or not, or is := $fh.readline, or whatever. Keep it simple. my $i = 0; while <$i> { Should integer.next() be operator:++ ? :-) > <$iter> # Calls $iter.next > fibs() # Returns iterator object > <fibs()> # Returns iterator object and calls that > # object's C<next> method (see note below) > In a list context: > > <$fh> # Calls $fh.each > <$iter> # Calls $iter.each > fibs() # Returns iterator object > <fibs()> # Returns iterator object and calls object's C<each> > > > So then: > > for <$fh> {...} # Build and then iterate a lazy array (the > # elements of which call back to the > # filehandle's input retrieval coroutine) (FWIW: I think they call .next(), and .next() can call the input retrieval coroutine or not.) Okay, I think I'm seeing why the lazy array bit is needed. So is it true that an iterator must be arrayificable? Or listificable? Also, what happens when <$fh> or <$iter> is called in scalar context within a loop? Surely that must update the "secret" iterator that is being run by the loop control? That is: for <$fh> { ... if /$start_of_block/ { my $block = ""; while <$fh> { leave loop if /$end_of_block/; $block ~= $_; # Or WFE the string concat operator winds up. } } } The two loops must update the same iterator, so any "lazy array" bits have to update as well. Ah well, that's for Dan &co. =Austin