On Tue, May 01, 2012 at 09:11:22AM -0700, Carl Mäsak wrote: > <tadzik> r: for $*IN.lines -> $line { say $line.lc } > <p6eval> rakudo 4c241c: OUTPUT«land der berge, land am strome, [...] > <goraki> tadzik: masak: when I run either I don't get any output until > I hit ctrl-d to "end" the input. > <masak> goraki: let my try locally. > <masak> my gosh, you're right! > * masak submits rakudobug > [...] > <masak> lines() is supposed to be lazy.
Actually, as implemented lines() is already "lazy": pmichaud@kiwi:~/p6/rakudo$ ./perl6 > my @a := $*IN.lines().map( { .lc.say } ); 1; 1 > say @a[0] HELLO hello True > The problem is actually in the .map code itself (I suspect a misoptimization) -- when map is attempting to reify multiple elements, it's batching up the required number of elements before processing any of them: > @a[3] WORLD GOODBYE WORLD world goodbye world > The problem line is in src/core/MapIter.pm: my $munched := $!list.munch($argc * $count); This causes all of the requested elements of the source $!list to be reified before any of them are processed, thus .map isn't properly lazy. This line was added as an optimization to make some .map operations faster, but lost some of the lazy aspects of map (as well as other things). The correct approach is to make .munch sufficiently performant over repeated calls (avoiding repeated shifts of the underlying list structures), which I plan to take care of shortly. Pm