One of the most awaited features of Microsoft .NET 2.0 is generics. Generics promise to increase type safety, improve performance, reduce code duplication and eliminate unnessecary casts. The most obvious application of generics in the framework class library are the generic collections in the new System.Collections.Generic namespace. Much has been written about those, but they are not the topic of this article.
Generics and arithmetics
The purpose of this article is to examine what generics have to offer for creating generic arithmetic types. As it turns out, not much.
Why this is important
One of the main applications of templates in C++ is to write generic arithmetic types. Surprisingly enough, doing this is not possible with .NET generics. Some people might think that generic arithmetic types are a fringe application, but everytime you draw a line using System.Drawing you use types such as Point and PointF that could benefit from a generic implementation. Another area where generic arithmetic types are important is the very large field of numerical programming, including mundane types such as vectors and matrices as well as more esoteric types like complex numbers and quaternions.
The Problem
Let us for example try to write a generic class to represent a point on a 2D surface. This is a very common data structure that is used for drawing and storing shape data. See for example the Point and PointF structures in the System.Drawing namespace, which could be implemented as a single type using generics.
(The samples in this article are written in C#, but the same problem exists for all .NET languages including VB.NET)
struct Point<T> { T x,y; public Point<T>(T x,T y) { this.x=x; this.y=y; } public static T operator +(T a,T b) { return new Point(a.x+b.x,a.y+b.y); } ... }
This structure could then be used like this:
Point<int> p1; //a point with integer coordinates, like System.Drawing.Point Point<float> p2; //a point with single precision floating point coordinates, like System.Drawing.PointF Point<double> p3; //a point with double precision floating point coordinates.
Something like this would work in C++, since it does not put any constraints on type parameters. But in .NET type parameters without any constraints are assumed to be of the System.Object type, so there is not much you can do with them.
Obviously there should be some way to constrain the type paramter T so that T has a + operator, like static T operator +(T a, T b).
But (presumably in the interest of simplicity), there exists no way to constrain type parameters by requiring the existence of certain operators or methods. The only way to constrain type parameters is by requiring the type to inherit a base class or to implement an interface. (There is one special case of a method constraint, the new() constraint which requires the existence of a parameterless constructor. But this is useless in this case.)
Interface constraints are a bit limited because interfaces can not contain static methods or operators. The canonical example for an interface constraint is the IComparable<T> interface constraint that is used in the System.Collections.Generic namespace whenever a type has to be constrained to have an order (for example in the SortedList<T> class). You can only use the generic version of SortedList for types that implement the IComparable<T> interface. This makes sense since if you do not have an order, you can not sort. Fortunately all the basic data types such as System.Int32 (int) and System.Double (double) implement this interface.
A similar interface should exist for types that support certain arithmetic operations. An interface for types that support all basic arithmetic operations might look like this:
interface IArithmetic<T> { T Add(T a); T Subtract(T a); T Multiply(T a); T Divide(T a); }
Since there are some types like System.String that support addition but none of the other basic arithmetic operations, it might be a good idea to make this more granular by providing separate interfaces for the basic arithmetic operations.
interface IAddable<T> { T Add(T a); } ... interface IArithmetic<T>: IAddable<T>, ISubtractable<T>, IMultipliable<T>, IDivisible<T> {}
The problem is that the basic data types such as System.Int32 (int) and System.Double (double) do not implement such an interface, even though they support all the required arithmetic operations.
The net result is that something like the above-mentioned generic point class can not be designed to use the basic data types, which of course makes it totally useless. There exist various kludges to work around the issue. For example it would be possible to wrap the basic data types to make them support the required interface. But this requires a lot of additional code and results in unacceptably low performance.
Is there a solution?
Going back to C++ templates
First of all, there is one solution that I definitely do not want. To abolish type constraints and make .NET generics more similar to C++ templates. C++ templates are a compile-time feature much like a macro preprocessor and are thus not a good solution for a highly dynamic language such as C#.
IArithmetic<T>
The simplest practical solution would be to let the basic data types inherit an interface for arithmetic operations similar to the IComparable<T> interface. This would be a very small and unobtrusive change and offer great benefits for writing generic arithmetic types in C# and other .NET languages. No compiler or runtime changes would be nessecary. It is totally incomprehensible to me why microsoft has not done this.
Method Constraints
A more radical approach would be to support method constraints instead of just interface constraints. This would be quite complicated since you would have to specify the exact signature of the method you require. For example in the point class it is not sufficient to require that a class/struct has a + operator. You also have to specify what type the arguments and return value have. So the syntax would look somewhat like this:
struct Point<T> where T: T operator + (T,T), T operator - (T,T) { ... }
This is obviously much too complicated for a language like C# that strives to be simpler than C++. Method constraints would also require compiler and runtime changes, so the chances of something like this being implemented are quite low.
Implicit interface constraints
Another approach that has some of the benefits of method constraints without the arcane syntax would be implicit interface constraints. You would specify which methods you require in an interface, but classes would not have to implement this interface. They would just have to contain all the required methods with the right signatures.
struct Point<T> where T: implicit IArithmetic<T> { ... }
Here any T would be allowed that has the required methods Add, Subtract, Multiply, Divide with the right signatures. T would not have to explicitly implement the IArithmetic<T> interface, hence the name implicit interface inheritance.
This approach would IMHO be the most flexible one, but it would probably lead to a religious debate between the advocates of static and dynamic typing. It would also require changes to the compiler, so this is not likely to happen anytime soon.
The notion of an implicit interface has come up on several discussions about this topic. See for example
this discussion.
I hacked a small utility class that emits automatic wrapper classes called AutoCaster. Integrating something like this into the compiler should not be too hard, so wether to support implicit interface constraints is mostly a language design issue.
Conclusion
The only solution that has a chance to make it into .NET in this decade is to add the IArithmetic<T> interface to the basic data types. But there is really no good reason not to do this as soon as possible. System.Int32, System.Single etc. already implement interfaces such as IComparable<T>, so why not IArithmetic<T>?
As I mentioned before, this would require no compiler or runtime changes. All microsoft would have to do would be to add the IArithmetic<T> interface to the System namespace and let all the basic data types explicitly implement this interface. I have no access to the source code of mscorlib.dll, but at least with mono this is trivial to do.
References
The C# language specification, Version 2.0
The proposed IArithmetic<T> interface
A generic implementation of System.Drawing.Point using IArithmetic<T>
The mono version of the System.Int32 primitive type.
The mono version of the System.Int32 primitive type, enhanced to support IArithmetic<T>
About the Author
Rüdiger Klaehn works as freelance programmer. He is currently trying to start a company with some friends, but in germany that is a long and tedious process. He is very interested in functional programming languages and hopes that .NET will lead to a more widespread adoption in the industry.
If you would like to see your thoughts or experiences with technology published, please consider writing an article for OSNews.
I like your proposal for IArithmetic as a type constraint.
Would it be possible to write, say, a generic sorting function without having the primitives implicitly boxed? This can’t be done with java generics, and it’s a real shame (and pain) (in java it’s even worse, there’s no operator overloading.)
@Rüdiger Klaehn
Have you posted this on the suggestions (feature request) area of MSDN? I believe the site is http://lab.msdn.microsoft.com/productfeedback/ They seem to be taking and responding very well to suggestions with all upcomming development products including the .NET framework. I’ve already added two suggestions, one of which I think will be implemented in C# 2.0 or the next release version. If you haven’t I would go over there right away and get it in.
As far as Method Constraints, I believe these very features you speak of are mentioned in the C# 2.0 specs however I can’t recall if operator constraints are allowed.
Thanks for the insight.
Nice catch. Thanks for the nice writeup.
Hopefully Anders and Co. will address this deficiency before they ship C# 2.0 final.
But if they don’t, then what will the Mono guys do? Fix this “bug” by adding something like the IArithmetic interface even though .NET doesn’t have such a fix? Or leave something broken just because Microsoft’s implementation is broken? In a way, this could prove to be an interesting test of the relationship between Mono and .NET.
Nothing stops you from using reflection and checking your generic type in the constructor, albeit a bit slow, but an implementation (hashtable) could be easily used to cache entries.
We dont want C# to become the syntactic mess C++ has become. Many people prefer C# for exactly this reason!
You point out, that writing a wrapper class would be to slow, which is true. But adding the IArithmetic interface would only relieve you of the work of writing those wrapper classes, performance wise.
Even if the numbers will not be stored as objects but as real int and float fields, the generic code still has to call the Add method instead of just issuing the ADD IL opcode. In the end, this might save you a little space since just an int needs to stored, but the unnecessary function call remains.
What a great article. It walked you through solving the problem using current means. that showed why it was a problem. then it went on to propose many solution. Finally, it came out with a very reasonable solution and demonstrated its reasonableness.
We need more like this one.
After reading this article I realized that it was somewhat over my head as I am primarily a web developer that doesn’t have such issues much of the time. With that said, C# and .NET is supposed to work not only with different languages but also with different purposes (ie web applications). Maybe then the reason that something like your IArithmetic<T> (which I really have no understanding of whatsoever could have been left out because other languages such as C++ or C are available for performing more mathmatical type opperations. This is just a thought, and from what I understand, I do agree what you are talking about makes tons of sense. Good Article!
Can anyone please explain what generic is when it comes to programming ?
The way I understood it, not having to automatically box primitives was seen as the main advantage C# generics has over Java generics. Why would you want to throw away that advantage? Making primitives implement IArithmatic would mean you throw away primitives and make them all objects.
Making primitives implement IArithmatic would mean you throw away primitives and make them all objects.
They’d only be boxed when you refer to them through an IArithmetic variable. In the same way that they aren’t boxed just because they implement IComparable.
Besides, as far as I understand it the Microsoft runtime creates specialised instances of generic classes when the type parameter is a primitive type. In the example in the article, Point<int>, Point<float> and Point<double> would each be specialised for their respective parameter types, so that no IComparable boxing would be necessary.
That’s obviously a size-speed tradeoff.
C++ templates are a compile-time feature much like a macro preprocessor and are thus not a good solution for a highly dynamic language such as C#.
Eugenia: wild inaccuracies do not enhance the site’s reputation. Nor does this nonsense generate any interest in C#.
Only thing that is wrong with this sentence, is that I wouldn’t call C# as a highly dynamic (although it’s more dynamic than C++).
No, Chris is right. C# isn’t even more dynamic than C++. Maybe the libraries are. I have complained five times about the quality of the articles, to Eugenia, just like him. And every time I’m “moderated away.” I really like this site and I really don’t want it to become yet another /.
C# has some reflection support (unlike C++), which can be considered as dynamic feature.
Last I can remember there are a few definitions of the word dynamic. I took dynamic to mean run-time oriented if that makes sense. In other words when the word dynamic is used it can mean that something is happening at runtime. In this situations what could that be… oh yeah generic type substitutions. Just because the user of a langauge isn’t in control of dynamic features of a langauge doesn’t make them non dynamic. It is simply a different definition of the word dynamic which is used more regularly and maybe only recently so to mean langauge features that alow program constructs to by highly configureable by the user or the program itself (ex. code changes or runtime).
Unless I’m mistaking RTTI in C++ is reflection, no?
And it is a dynamic feature..
The biggest problem with RTTI in C++ is that it took a long time to be available so it is still not widely used..
But a new project starting now could probably count on the availability of RTTI..
I came up with a similar implicit interface idea a couple of years ago, but mine didn’t involve any extra syntax (i.e. more like C++). The compiler knows about the requirements of the parameter types for a generic type when it compiles the generic type, so it could compile in an implicit interface without the developer ever having to know about it. For generic classes that can get by with just System.Object operations, no interface would be required. For those requiring just the basic numeric operations, the compiler would compile a special-case generic class for the arithmetic types (polymorphic IL opcodes mean just one should be required) and a separate case generic with an implicit interface having the required overloaded operators. The compiler, upon compiling the instantation of a generic type, knows exactly what the capabilities of the parameter type are, just as in C++ and in the current C# generics, so ensuring the match against the required interface should be no problem, just as it is now for explicit constraints. Because the parameter type may be used in the generic instantiatiation separately from its definition (i.e. separate assembly), regular interface specification won’t always be possible. There are a number of solutions which don’t require engine modification, such as using wrapper classes, delegates, and reflection.emit.
The best solution, IMO, however, is to extend IL so that the instantating assembly can specify that the parameter type implements the implicit interface, and to modify the engine so that it can perform the interface mapping after the initial loading of the type. The engine already has to be able to generate vtables for interface-implementing classes which hook up method bodies to interface methods; it just needs to be made flexible enough to perform the mapping on demand rather than just at its initial type loading. This on-demand approach would also work well for purely dynamic types, both as generics and their parameters, and would incur no excessive overhead as would be required by purely compiler-based approaches. Perhaps I’m overlooking something, though; if so, please let me know.
Rich
I noticed I made a mistake: polymorphic IL opcodes wouldn’t eliminate the need for special cases for each of the primitive types, since they must also be stored as their concrete unboxed types (otherwise boxing overhead becomes a problem).
Rich
Yes, you are right, jeff, /current/ RTTI is *not* as complete reflection system as the .net/java reflection (altough XTI is).
But this fact does not change the fact that we are seeing many weak articles being published here at OSNews, as the current one.
There is a series of flaws in the current article: not very-well researched (restricted generics where thoroughly studied to inclusion in c++ during the last ISO std round), weak/incorrect comparisons with c++, boxing/unboxing not mentioned/considered.
OSNews used to be more strict/edited (editorialized?); altough Eugenia is _not_ completely unbiased, her articles are usually very good. But the other articles that are entering are deserving some questioning/polishing/removal of factual errors and flamebaits. IMHO.
Obviously, Eugenia can say to me: Zab, if you are not liking, leave. I’ll be hurt, but it’s ok.
Once again, please submit this to the microsoft feedback site I listed above. If not this release, maybe the next?
@Zab Ert
Got ya. I’ve noticed this site leaning a little tword particular technologies. Maybe people need to submit more news on the underdogs. And maybe Linux isn’t as much of an underdog anymore.
I really enjoy technical articles like this one the most. With that said, I think a seperate site that is more software technology oriented more than OS oriented may be a better place for such articles. Maybe OS news should be seperated into a few different new portals? I would end up going to them all most likely.
C++ templates _are_ just glorified macros; there’s nothing special about them at runtime. C# is certainly more dynamic than C++, unless, of course, C++ has obtained the ability to portably generate classes at runtime and I just didn’t get the memo. Also, the core parts of the IL library, including its reflection capabilities, are a part of the C# language specification; you can’t separate C# from those parts of the library and still call it C#.
Rich
C++ templates are a compile-time feature much like a macro preprocessor and are thus not a good solution for a highly dynamic language such as C#.
C# is a multi-purpose language, parts of it are static (e.g. normal method calls are resolved at compile time) and parts of it are dynamic (e.g. with Reflection you can call any method on an object without knowing the objects’ class).
This is a good thing because most of the time you are fine with static behavior and can thus benefit of compile time verification and good performance. Sometimes tough you need the dynamic behavior and are willing to deal with more errors at runtime and are also willing to sacrifice performance. Therefore, I absolutely don’t see why generics should not be suitable for C#. It allows you to uncover more bugs at compile-time and improves performance in a lot of areas.
Eugenia: wild inaccuracies do not enhance the site’s reputation. Nor does this nonsense generate any interest in C#.
If you accuse someone of producing wild inaccuracies you should definitely say what exactly those inaccuracies are and why you think so.
Regards,
Andreas
Jeff, I just checked the link you provided and it requires a passport account which I have no intention of getting. If you want to submit my idea, go ahead.
Rich
There is a series of flaws in the current article: not very-well researched (restricted generics where thoroughly studied to inclusion in c++ during the last ISO std round)
So? As the author says in the article, he wants to explore why .NET generics are not suitable for numerical programming. Mentioning what you suggest seems highly off-topic.
weak/incorrect comparisons with c++
What exactly are the weak/incorrect comparisons?
boxing/unboxing not mentioned/considered.
Why should he mention boxing/unboxing? Again, the article is about a problem of .NET generics and not about their benefits.
Regards,
Andreas
This was an interesting article. Btw, considering that you defined C# as a dynamic language (and surely it’s more dynamic than C++) it would be reasonable do what programmers in dynamic languages would do: use reflection to check if such method exist. this would happen at runtime, so the stati crew may disagree. Or you could do like Nice does : allow a developer to declare interfaces and to say that some classes implements them after the class has been created, like:
class Foo {…}
interface Ifoo{…}
class Foo implements Ifoo {}
You’re complaining that you can’t limit your template based on the availability of arithmetic operators.
So, did you try to compile your generic example above (Point<T>) using an object where the + operator would not apply?
All of the base primitives would work fine in your example.
However, if I read the spec correctly, as soon as you try create a struct/class that doesn’t support + (we’ll call it “Foo”), and try to declare it (“Point<Foo> f;”) and use it (“f=f+f;”), you should get a compile-time error.
…you went on to ramble about the problem with .NET generics and completely left out of the issue of generics not being CLS compliant yet.
What about the Eiffel way?
They do stuff like:
class interface HASHED_SET[E->HASHABLE]
— etc.
end
meaning that HASHED_SET is generic over E, and E has to inherit from HASHABLE. This is the simplest/cleanest syntax for constrained genericity I have encountered.
This is a bit of a weird statement: “much like a macro preprocessor and are thus not a good solution for a highly dynamic language such as C#.”
Macros are orthogonal to the dynamic properties of a language. Currently, the languages that have the most evolved macro systems (Lisp, Scheme), are also among the most dynamic languages available.
Macros in C++/C are quite different from Lisp Macros, wouldn’t you say? From toying around with lisp, I’ve come to understand that lisp macros are actually pieces of logic while C macros are just text-substitution commands.
Would it be possible to write, say, a generic sorting function without having the primitives implicitly boxed
Yes. One of the reasons why generics were introduced is that they allow you to write much better performing code. .NET 1.1 sorting can be up to 5x slower than C++ sorting. .NET 2.0 is only roughly 2x slower.
Regards,
Andreas
Rich: You and I may have different ideas of what “glorified macros” means. C++ templates do more than just plop code in place; at compile time, the compiler can figure out a lot through templates about what class to generate. Specialized templates are an example of this. The template system is actually turing complete; I’ve seen it used to solve problems. The current C/C++ User’s Journal also has an interesting article about using templates for loop unrolling.
I also fail to see how C++ could be considered as dynamic as C# or Java (I’m a java guy so I’ll stick with it in this discussion). To me dynamic means e.g. initializing a class where only a name is known, inspecting objects. I see some cumbersome workarounds (shared libraries are kind of) but for the runtime analysis and dynamic invocation of arbitrary objects I don’t see any simple approach in C++. [If your point is that everything can be implemented in assembler that can be implemented in any other language then I’m fine with that argument, but certainly calling assembler object oriented or the like would make you appear a bit strange…]
How would you describe templates briefly? I think Eugenia’s sentence has some valid points: Template instantiation happens at compile time (in contrast to c#). Instances of templates do not share a common type (whereas java generic types have more relation [wilcard operator]).
Stefan: Briefly, templates are a mechanism to allow generic programming. They allow C++ functions and classes to be type-agnostic, and to be so effeciently.
I agree that Java and C# are more “dynamic” than C++, because they both have a run time environment, whereas C++ does not. C++ has different design goals than Java and C#, so I don’t consider that a problem.
I wouldn’t use Java’s generics as a useful standard. As of 1.5, Java’s support for templates/generics really only saves some typing. A Java generic always uses Object as the templatized type, and inserts the approrpriate castings so that the code is type safe. And that’s the reason why different instantations of a Java generic can be related to each other: they’re trivially related because they all use Object. C++ (and C#) generate actual classes with that type explicity in place.
* initializing a class dynamically: COM and sons, CORBA and sons, etc…
* runtime analysis and dynamic invocation: XTI
* template instantiation, yes, occurs at compile-time (so they are absolutely typesafe).
* instances template types CAN share common “root” type, if you need (generally you don’t).
Yes, Lisp macros are vastly more powerful than C++ macros + templates, but in the end, both are mechanisms that allow changing of program behavior at compile-time. Meanwhile, “dynamism” allows changing of program behavior at runtime. The two mechanisms have nothing to do with each other — you can have fully static languages with a macro processor (Ocaml with Ocaml4P), fully dynamic languages with no macro processor (Smalltalk), or fully dynamic languages with a macro processor (Lisp). That’s really why I think the author’s statement was weird — templates being compile-time macros have nothing to do with the dynamism of the underlying language.
Why can’t we implement the solution using wrapper classes integrated into the language definition (I think this is essentially what the article suggests) and then count on compiler optimizations to deal with the speed issue. This way the language/standards would require the least amount of change but compilers could choose to still implement these interfaces with just a simple + opcode?
I’m probably missing someone but am wondering what it is. Basically it seems like we only need a simple check to see it it is one of the primitive + operations and if it is just pretend all the interface stuff used isn’t there.
* initializing a class dynamically: COM and sons, CORBA and sons, etc…
Both of which require extra-lingual functionality. If used with IDL (as both usually are), both are “grafted on,” introducing their own types, own declaration syntax, specialized compilers (IDL compilers), etc. C++ does not allow you to load a class dynamically any more than asm does. It *can* be done in both, but it’s not realistic to say-so because it requires significant support outside the language itself.
* runtime analysis and dynamic invocation: XTI
XTI doesn’t exist in any usable form, yet. Maybe it’ll be in C++ 0x, but it’ll be 2010 at least before that get’s widespread compiler support.
* template instantiation, yes, occurs at compile-time (so they are absolutely typesafe).
Type-safe templates in C++ are like airbags in a rocket.
Yes, that would work. Essentially, what you’d be doing is getting rid of primitive types entirely and making everything be an object of a class. In practice, compiler technology is good enough at inferring the type of variables that they can usually eliminate the “object” overhead.
The dynamic vs. static discussion is beside the point.
From a programmer’s perspective, generic classes in C# are instantiated and type-checked at compile-time, as are C++’s template classes. (How compiler and run-time system implement them is another matter.)
Yes, reflection in C# allows generic classes to be instantiated at runtime, but that’s more complicated, more error-prone and slower, so it should only be done where the added flexibility is absolutely necessary.
Another difference between C# generics and C++ templates is much more significant. C# supports type parameter constraints and type-checks generic classes much like normal classes, whereas template classes are type-checked whenever they’re instantiated.
C++’s concept is more flexible but has two significant drawbacks. First, type correctness of a template can not be proven by the compiler and has to be ensured through test instantiations, which of course can leave untested cases. Secondly, violations of the implicit constraints on template arguments lead to unhelpful error messages somewhere inside the template.
Recent C++ compilers can do some type-checking on templates, but that can only ever be partial because there are no explicit type constraints to check against.
The “Boost Concept Checking Library” for C++ uses some ingenious macro hackery to allow explicit template constraints and provide better error messages. But again that’s only a partial solution because the template writer isn’t required to provide these and the compiler cannot check that the template code actually adheres to the constraints.
andy: Stroustrup wrote an interesting paper on the direction future C++ standards might go with concept checking. I read it a few months ago, so I can’t recall the details, but I do remember being impressed with it, and thinking it was a more robust solution than what C# is doing.
Concept checking – A more abstract complement to type checking
http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1510.pdf
C++ templates are a compile-time feature much like a macro preprocessor
Andreas:
You’re right; I should’ve been more detailed.
Comparing a macro preprocessor with a Turing-complete ‘found’ language like C++ templates, and says the one is ‘much like’ the other could be an indicator that one hasn’t been looking at http://boost.org of late, nor read stuff like http://www.moderncppdesign.com/book/main.html or http://www.josuttis.com/tmplbook/
When you don’t have time to delve into every technology (and who does) some (like me) key in on statements like the above as litmus tests for whether the author is worth reading.
Chris:
I agree with you comparison macros vs. templates.
I completely misinterpreted your very first post. I did not realize that you quoted the first sentence from the article and therefore took it as your own writing. Out of context, I thought that you think that generics are not a good solution for a highly dynamic language like C#.
You are right that this sentence in the article is easily misunderstood. However, I think the author wanted to say that he doesn’t want generics to be a compile time only construct as they are in C++ and Java (templates do not exist in the compiled code, only instantiated templates do, as normal classes and normal functions).
Sorry,
Andreas
It’s certainly true that the current constraint system of generics in .NET isn’t as rich as it could be. We are exploring where it makes sense to extend it in the future, but there will be no changes to the current scheme in C# V2.0. Note that any change to the generics constraint syntax impacts all .NET languages, so it’s not just a C# thing.
There’s one technique to make it a little nicer to write such things, though the perf isn’t up to a hand-coded approach. See http://blogs.gotdotnet.com/EricGu/commentview.aspx/0efca2aa-0c7c-4a… for more information.
The IArithmetic<T> proposal would not require any changes to the constraint syntax. It would just require the base data types to implement another interface in addition to IComparable<T>.
I already came up with the IntCalculator approach, but since it involves a method call that is currently not inlined it is much too slow for my application (complex numbers and vectors).
But it is nice to know that you at microsoft are at least thinking about the problem.