Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unexpected Non-Laziness

I wrote this code for this weeks challenge to produce ugly numbers.

sub factors( $n ) {
  if $n > 1 {
     $_, |factors $n div $_
      given ( grep $n %% *, 2..* ).first } }

.say for ( 1, |grep *.&factors.all ∈ ( 2, 3, 5 ), 2..* )[^150];

This works, in the sense it produces the correct ouput, but it does not behave lazily: The output does not start right away but 30 seconds after the start.

However when I remove the indexing and iterate over the bare sequence

.say for 1, |grep *.&factors.all ∈ ( 2, 3, 5 ), 2..*;

I get output immedeatly as expected.

This is a bug, yes?

like image 318
Holli Avatar asked Jul 26 '21 21:07

Holli


1 Answers

This is not a bug (though could possibly be documented better). Indexing with [] reifies the elements it indexes over, so [^150] computes a (non-lazy) list of the first 150 elements. (The rest of the list remains lazy, but those initial elements do not).

If you want to iterate lazily, you can use &head instead, which would give you the following final line:

.say for ( 1, |grep *.&factors.all ∈ ( 2, 3, 5 ), 2..* ).head(150);
like image 185
codesections Avatar answered Nov 08 '22 23:11

codesections