Cheating Linq

A couple days ago I had a fun idea running through my head. What if one could take the standard linq function Concat() and have it “consume” its own output as the input which created the output, a paradoxical call if you will. This can be represented with the following F# like pseudo-code:

Let y be 1…100
Let x be y.Concat(x)

While this can not be done in C# directly, via a little trickery with a lambda and a modified closure it is possible.

static void Main()
{
/*Pseudo code
* Let y be 1 ... 100
* Let x be y.Concat(x)
*/
var oneToHundred = Inc(0).Take(100);
IEnumerable x = null;

var oneToHundredRepeated = oneToHundred.Concat(DelayedAssignment(()=>x));
x = oneToHundredRepeated;

foreach (var i in oneToHundredRepeated)
{
//Write 1..100 out to the console over and over
Console.WriteLine(i);
Thread.Sleep(10);
}
}

private static IEnumerableInc(int startingValue)
{
yield return startingValue + 1;
foreach (var i in Inc(startingValue +1))
{
yield return i;
}
}

private static IEnumerableDelayedAssignment(Func> enumerationGetter)
{
//This loop appears to be a waste of syntax, but really it causes the compiler to build a statemachine which
//will not realize the state enumerationGetter until someone tries to enumerate over this method
//better ways of doing this, but this is the easiest
foreach (var value in enumerationGetter.Invoke())
{
yield return value;
}
}

Modifying the closure makes the call to Concat no longer functional and thus difficult to reason about. However, it is still quite a cool trick.

Previous Post