Курс языка программирования Raku / Продвинутый уровень / Порядок выполнения / Префиксы инструкций

Ленивость и немедленность

Некоторые списки в Raku вычисляются только тогда, когда их элементы действительно нужны — они ленивые. Префиксы lazy и eager позволяют управлять этим явно.

Префикс eager заставляет список быть вычисленным целиком, немедленно:

my @squares = eager (1..3).map(* ** 2);
say @squares; # [1 4 9]

Без eager map всё равно выдаст значения, но eager гарантирует, что все они будут вычислены прямо здесь и сейчас, а не по запросу.

Префикс lazy делает противоположное: он помечает список как ленивый, и его элементы создаются только при обращении к ним. Именно это позволяет списку быть концептуально бесконечным:

my $numbers = lazy (1 .. Inf);
say $numbers.is-lazy; # True

Метод .is-lazy подтверждает, что список не будет пытаться вычислить все свои (бесконечные) элементы заранее.

Этот конкретный пример как раз тот случай, когда Raku и так предполагает ленивость: неограниченный диапазон вроде 1 .. Inf уже является ленивым, поэтому say (1 .. Inf).is-lazy напечатает True и без префикса. Использование lazy здесь ничего не меняет — оно лишь делает намерение явным. Префикс по-настоящему полезен, когда нужно сделать ленивым список, который иначе был бы вычислен нетерпеливо.

В большинстве случаев Raku сам делает разумный выбор — диапазоны и последовательности ленивые, обычное присваивание массиву нетерпеливое. Используйте эти префиксы, когда нужно переопределить этот выбор: eager, чтобы форсировать затратное вычисление прямо сейчас, lazy, чтобы отложить вычисление, которое может быть большим или неограниченным.

Навигация по курсу

Тест — do   |   sink и quietly


💪 Или перейдите сразу к упражнениям этого раздела.