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

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
Leave a comment

1 Comment

  1. I left this comment on your old blog. If you like this you’ll really like recursion in lambda calculus using fixed-point combinators.


Leave a Reply to Michael Welch Cancel reply