Tag Archives: deferred execution

Counting the infinite sequences

Doesn’t it strike you as odd, that you can write such code in C#:

if (sequence.Any()) ...

and it is efficient as it can be, but when you rely on Count method:

if (sequence.Count() > 0) ...

you may fall into a trap of extensive computation despite you just need confirmation whether the sequence is empty or not. Well, this disparity annoyed me for a long time and all I could think of was passing somehow a predicate to Count. It is as fishy as it sounds, and it annoyed me even more.

Until the perspective changed — who said Count should count anything? Why Count should jump right away with exact answer?

Count should be lazy and it should simply return the instance of some numeric like type, say SequenceCount — that type should keep reference to the sequence, have implicit conversion to Int and — what is crucial — it should also overload comparison operators. With all those goodies you could finally write:

// Skila syntax
if (1...).count() > 0 then 
  stdOut.writeLine("not empty");

to see a printout after a few CPU cycles.

Now when I solved this issue I can think of general lazy evaluation design for Skila…

Tagged , , , ,

Don’t mix deferred execution with optional outcome

I prefer using yield when returning IEnumerable because code looks really clean — storing the output manually loses this nice look, not mentioning extra wrapper method.

But the look can be misleading when the language design leaves a hole — and I fell into this trap. I used yield in method that returns not some crucial data, but simply a report about what was not computed. You can read it, display it, or ignore it, your call. The problem is yield unlike cached result, uses deferred execution. And deferment is based on usage of… the outcome. So if you ignore it (and C# compiler does not make a peep about it), it will be not executed at all.

The lesson for C# devs is this — if it is OK to ignore the outcome of the method (as in my case, just a summary of computation), do not use yield. Go with storing the output inside the method.

Tagged , ,