Larry wrote:

So you can do it any of these ways:

    for <$dance> {

    for $dance.each {

    for each $dance: {
                   ^ note colon

Then there's this approach to auto-iteration:

    my @dance := Iterator.new(@squares);
    for @dance {
Okay, so now I need to make sense of the semantics of <...> and
C<for> and coroutines and their combined use.

Is the following correct?

==============================================================================

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

	each()			# returns a lazy array, each element of which
				# is computed on demand by the appropriate
				# number of resumptions of the coroutine body


In a scalar context:

	<$fh>		# Calls $fh.readline (or maybe that's $fh.next???>
	<$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)

	for <$iter> {...}  # Build and then iterate a lazy array (the elements
			   # of which call back to the iterator's coroutine)

	for fibs() {...}   # Loop once, setting $_ to the iterator object
			   # that was returned by C<fibs>

	for <fibs()> {...} # Build and then iterate a lazy array (the elements
			   # of which call back to the coroutine of the
			   # iterator returned by C<fibs>


==============================================================================

Note: this all hangs together *very* nicely, except when someone writes:

	loop {
		my $nextfib = <fibs()>;
		...
	}

In which case $nextfib is perennially 1, since every call to C<fibs>
returns a new Iterator object.

The solution is very simple, of course:

		my $nextfib = <my $iter//=fibs()>;

but we might want to contemplate issuing a warning when someone calls
an argumentless coroutine within a scalar context <...>.

Damian

Reply via email to