Can a finite list be lazy in Perl 6?

Yes, you can, using lazy method:

> my @b = (0 ... 3).lazy;
[...]
> say 'Is @b lazy? ' ~ @b.is-lazy;
Is @b lazy? True

There's nothing special Seq that make it be lazy, just its underlying Iterator does.


The "is-lazy" method, in my opinion, is really a misnomer. The only thing it says, as cuonglm pointed out, is that just passes on that the underlying iterator claims to be lazy. But that still doesn't mean anything, really. An iterator can technically produce values on demand, but still claim it isn't lazy. And vice-versa.

The "is-lazy" check is used internally to prevent cases where the number of elements needs to be known in advance (like .roll or .pick): if the Seq / iterator claims to be lazy, it won't actually try, but fail or throw instead.

The only thing that .lazy does, is wrap the iterator of the Seq into another iterator that does claim to be lazy (if the given iterator claims it isn't lazy, of course). And make sure it won't pull any values unless really needed. So, adding .lazy doesn't tell anything about when values will be produced, only when they will be delivered. And it helps in testing iterator based logic to see how they would work with an iterator that claims to be lazy.

So, getting back to the question: if you want to be sure that something is lazy, you will have to write the iterator yourself. Having said that, the past months I've spent quite a lot of effort in making things as lazy as possible in the core. Notably xx N still isn't lazy, although it does produce a Seq nowadays. Making it lazy broke some spectests at some deep level I haven't been able to figure out just yet. Looking forward, I think you can be sure that things will be as lazy as makes sense generally, with maybe a possibility of indicating favouring memory over CPU. But you will never have complete control over builtins: if you want complete control, you will have to write it yourself.