Post

# Functional Programming with C#: Lazy Calculation

• 18.7k
• 0
• 0

For this demonstration, we'll be creating a lazy-calculated prime number generator based on Mike's code.  First, we'll be needing a utility method to generate a steady stream of numbers (we only need odd numbers after 2)

public static IEnumerable<Int32> Counter(Int32 start, Int32 step, Int32 min, Int32 max)
{
Int32 current = start;

while (current > min && current < max)
{
yield return current;
current += step;
}
}

Next, we'll need a method that will tap into our program flow to perform some processing but not inturrupt the output.

public static IEnumerable<T> PassThrough<T>(this IEnumerable<T> items, Action<T> act)
{
foreach (T item in items)
{
act(item);
yield return item;
}
}

These two simple methods will allow us to generate all the prime numbers that can be expressed with an Int32 variable.

public static IEnumerable<Int32> GetPrimes()
{
List<Int32> found = new List<int>();

return
new Int32[] { 2 }
.Concat(Helpers.Counter(3, 2, 0, Int32.MaxValue))
.Where(i => !found.Exists(j => i % j == 0))
}

Let's examine what is happening in the code.  First, we'll start with the number 2 and then append all the odd numbers from three through Int32.MaxValue. As each of the numbers is generated and passed through the function chain, we'll check to see if it is evenly divisible by any item in the collection of primes we are accumulating.  If not, it is a new prime and we'll add it to our "found" list and pass it through using the iterator in the "PassThrough()" extension method.

The really cool thing is that we only calculate what's needed when it is neede which is what gives us "lazy calculation" of our primes. As a result, when we consume this method and only request the first ten primes, the minimum amount of computations are be performed to get what we have requested.

static void Main(string[] args)
{
Helpers
.GetPrimes()
.Take(10)
.ForEach(i => Console.WriteLine(i));