Some background - and why I avoid yield in certain library code I'm writing:
All About Iterators – Yet Another Language Geek[
^]
The problem is this:
Say I need to do simple set combinations using loops. In LINQ-ish fashion I'll simply be treating a forward iterable sequence as a collection or a col, below.
so for a union of col a and col b I do a|b
to yield that would look like
Union(a,b) implemented as Figure 1, whose performance has now decreased significantly due to the internals of how this works.
it's bad enough that it has been suggested by brighter minds than mine that a feature be added to C#: yield foreach, as in Figure 2, to both increase readability and sidestep the performance hit required (because it can compose the iterator classes into one)
Right now I hand roll a lot of enumeration stuff, because LINQ performance is unacceptable for extensive use in things like GLR parsers, and part of it is this limitation of yield.
I've nearly wanted to move off of .NET altogether because F# is an odd duck and c# just is causing me a lot of work. To the point where I've considered moving back to my good old C++
This isn't about bit twiddling. I'm not looking to shave clock cycles. This is a design issue that impacts where I can even use LINQ and yield within C# specifically - it limits where I am able to practically use it, because of the nature of the projects I work on which deal in a lot of parsing, decision trees and pattern recognition, and use these with wild abandon everywhere, and nesting is the typical case.
I work around this right now by hand coding quite a bit.
Is anyone else familiar with this problem, and if so do they have any good suggestions where I can continue to use C# with or without LINQ and the modern C# paradigms without hitting performance barriers once I want to employ set based functional programming?
What I have tried:
IEnumerable Union(IEnumerable a,IEnumerable b) {
foreach(var x in a) yield return x;
foreach(var y in b) yield return b;
}
IEnumerable Union(IEnumerable a,IEnumerable b) {
yield foreach a;
yield foreach b;
}