8

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?

Holli
  • 5,072
  • 10
  • 27
  • a related point arose in a recent blog gfldex.wordpress.com/2021/08/02/only-infinite-elements from gfldex ... with [^∞] as the reifier – librasteve Aug 03 '21 at 07:48

1 Answers1

10

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);
codesections
  • 8,900
  • 16
  • 50