Lazy Evaluation using “IncrementalObject” in Mathematica 15
Wolfram Mathematica ver 15 contains many new features. One that appeals to me immediately is its support for lazy evaluation (“generator”). Working with huge sequences is now manageable!
I am referring to “IncrementalObject” and “NextValue” functions.
Let us first understand the basics. See the example below:

The above generates a range of integers, to be exact, 1 to 4. Of course I can generate a much larger range as well.
The following generates a permutation of the 4 integers 1 to 4.

There are 24 elements in this size. The size will grow significantly if we use a larger range argument. It is easy to create permutations with size of 1 million or more! Such a large set consumes significant memory and is also compute intensive. What if we have to iterate over such large collections to accomplish a task?
This is what “IncrementalObject” attempts to tackle. See the example below.

Now we are modeling the same “Permutations” as earlier, but this does not result in the complete set being created. An incremental object is a symbolic handle on a sequence of values that produces them one at a time, on demand. Nothing is computed until we ask.
So how do we get the values from this collection? We use “NextValue” function. See below:

Note that we use “NextValue” with the handle returned from “IncrementalObject”. And each time we call it, it returns the next value from the collection (it remembers the state). Therefore we have to be careful when we share the handle. Take a look at the following example.

The point to note is that we are sharing “counter” (handle) returned from the first “IncrementalObject” call with the second call by passing it as an argument (in fact, this shows the cascading or composing capability). That is why, even though we call “NextValue[evens]”, it indirectly modifies the state of “counter” as well!
Thus “IncrementalObject” and “NextValue” are extremely useful in modeling large collections in Mathematica – something that has been missing all along! In addition to “Range” and “Permutations”, “IncrementalObject” works with several other functions such as “Subsets”, “Tuples”, “Map”, “Select”, “Take”, etc.
Is this type of lazy evaluation unique to Mathematica? Not at all. Haskell, Python, Scala, C#, and Clojure are some languages that support this idea. Even C++ has “range views” (std::views) that are lazily evaluated.
You can download the code from here.
Have a great week!