Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implicitly lazy gather/take not considered a "lazy" object

The documentation for gather/take mentions

Binding to a scalar or sigilless container will also force laziness.

However,

my \result = gather { for 1..3 { take $_² } };
say result.is-lazy # OUTPUT: «False␤»  

Same happens if you use a scalar, and binding using := Is there some way to create implicitly lazy gather/take statements?

Update: It's actually lazy, only it does not respond to the is-lazy method in the expected way:

my $result := gather { for 1..3 { say "Hey"; take $_² } };
say $result[0] # OUTPUT: «Hey␤1␤»

So the question is "What are the conditions for is-lazy to consider things actually lazy?"

like image 932
jjmerelo Avatar asked Apr 15 '19 11:04

jjmerelo


1 Answers

I think the problem is really that you cannot actually tell what's going on inside a gather block. So that's why that Seq object tells you it is not lazy.

Perhaps it's more a matter of documentation: if is-lazy returns True, then you can be sure that the Seq (well, in fact its underlying Iterator) is not going to end by itself. If is-lazy returns False, it basically means that we cannot be sure.

One could argue that in that case is-lazy should return the Bool type object, which will also be interpreted as being false (as all type objects are considered to be False in boolean context). But that would at least give some indication that it is really undecided / undecidable.

like image 193
Elizabeth Mattijsen Avatar answered Nov 03 '22 00:11

Elizabeth Mattijsen