My take on it:

The 'for' loop does bind $_ to alias each item of the list in turn. But, "the list" is not synonymous with the variable named @a. However, the = operator operates on "the list" itself, not the container, replacing the elements in the existing Array (or whatever) object. So, the first iteration through the loop would indeed replace all the elements in the object being iterated over.

The semantics of the 'for' loop are sequential. It is a programming-flow construct, not a data-manipulation construct. So laziness within the list is not an issue. If some elements are delayed-evaluation, they get overwritten so that evaluation is never done.

The follow-up question is more interesting. The operation of @a,@b makes a new List object. Just like =after= calling $c=$a+$b it does not matter if you change $a. Imagine + being lazy with thousand-digit numbers so it might avoid actually doing it 'till you needed (if ever) the answer. It would be unacceptable if it appeared to bind to the original arguments indefinitely. If the comma concatenation is "lazy" it needs to be on a deeper level so it does not seem to depend on the arguments not changing afterwards. It might, in particular, copy all the primitive components out of @b which includes range objects and other lazy lists, or arrange a copy-on-write sharing with @b. I've done this kind of stuff with my C++ classes, so I'm familiar with the scenario. That is, give the outward appearance of "value semantics" but share storage or defer work internally. @a,@b produces a well-defined value.

So, the first example prints "1" only, and the second prints 1 through 8.


Patrick R. Michaud |Perl 6| wrote:
I think my question can be best understood by example -- what
does the following produce?

    my @a = 1,2,3,4,5;
    for @a { .say; @a = (); }

My question is whether the change to @a inside the for loop
affects the iterator created at the beginning of the for loop.
In other words, would the above produce "1\n2\n3\n4\n5\n"  or
"1\n" ?

My followup question is then:

    my @a = 1,2,3,4,5;
    my @b = 6,7,8;

    for @a,@b { .say; @b = (); }

I have more examples involving various aspects of list and
iterator semantics, but the answers to the above will help guide
my questions.


Reply via email to