R/MRatCalcpowered by RiXOpen calculator

RiX walkthrough · 7c

Lazy generators

Contrast eager arrays with cached sequences that produce values on demand.

Eager and lazy answer different questions

Use |; when you want a finished array now. Its number counts values that actually reach the output, including accepted seeds.

Runnable RiX

Use |^ when you want a lazy sequence with a known ceiling. RiX creates the sequence immediately but waits to calculate its values until something asks for them.

Runnable RiX

A chain with a source and no terminator is lazy and unbounded. Positive indexing remains safe because it only advances far enough to answer the request.

Runnable RiX

Inspect a bounded part

Lazy sequences are one-based, like ordinary RiX arrays. A positive bounded slice generates through its far endpoint and returns an ordinary finite array.

Runnable RiX

The index passed to |: is also one-based. The first square is therefore 1^2, not 0^2.

When the lazy limit is numeric, RiX knows the eventual length without materializing every value.

Runnable RiX

Map and filter without becoming eager

Map and filter pipes preserve laziness. In this example the filter examines natural numbers until it has found six even values; the map only doubles the values demanded downstream.

Runnable RiX

Filtering does not spend an output slot. Compare that behavior with this eager chain: candidates that fail |? still advance the arithmetic source, but only successful values count toward |; 5.

Runnable RiX

Generate from recent history

When |> is the primary source, _1 means the most recent source value, _2 the second most recent, and so on. RiX passes only the requested history slots; it does not construct a growing history array for every call.

Runnable RiX

The explicit 1, 1 values initialize the history source. If a requested placeholder has no seed behind it, RiX reports the missing history instead of inventing a value.

Predicate bounds

A predicate can bound either eager or lazy work. The triggering value is part of the result.

Runnable RiX

The lazy form evaluates the same rule only as values are requested.

Runnable RiX

Because a predicate-bound sequence has no known length until it finishes, operations such as negative indexing, reverse, sort, and Last should be used only after a finite sequence has been materialized.

Snapshot or restart lazy state

A shallow copy receives its own producer and cache at the current point. A deep copy restarts from the generator definition and its original seeds.

Runnable RiX

Aliases made with = still share one lazy value. Lazy sequences themselves are structurally immutable; materialize a bounded sequence before using array mutation methods.

Runnable RiX

Walk with an iterator

An iterator adds a traversal cursor without putting cursor state on the lazy sequence itself. A new iterator starts at index 0, before the first item. Next moves first and then returns, so its argument controls how far the cursor moves.

Runnable RiX

Here Next(2) skips the first item and returns item 2. Peek(3) reads item 5 without moving from index 2. Negative steps move backward, while Next(0) returns the current item without moving. Lazy reads share the source cache, so looking ahead calculates only the values needed to reach that position.

Reset(index) positions an indexable iterator at an item; Peek() reads that item and the next Next() moves onward. An empty reset returns to cursor 0.

Runnable RiX

Crossing the end with Next puts the cursor in its done state. Done() uses the usual RiX truth convention: 1 means done and null means not done. Being on the final item is not done until another advancing read crosses the end.

Runnable RiX

Iterators also work over eager arrays, tuples, strings, tensors, maps, and sets. A shallow copy gets an independent cursor at the same position while continuing to read from the same source.

Safety is separate from meaning

|; 5 means five successful outputs, not five attempts. RiX also maintains an operational iteration limit so a filter that can never succeed raises a clear error rather than hanging or silently returning a truncated array.

Keep going

Use the interval generation lesson to create lazy ranges with exact endpoints, then compare deterministic ranges with seeded rational sampling.