rakkarage's picture

generic vector?

why not use generic classes for vector and matrix? then you could use one class for d, f, and h?

i know it would make no difference at all to how people use the code but i was curious about why

it's just to prevent people writing Vector2<string> or other nonsense?

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
kvark's picture

I guess there can be no generic vectors in .NET.
if the generic argument is T, then how does the compiler know about + and - operators on it?
Generally, we have to specify interfaces 9with those operators defined), but here we want to use basic types, which doesn't expose interfaces...
Am I right?

the Fiddler's picture

kvark is right, this is a general limitation in the .Net framework.

The sticking point is that operators are always static and static members cannot be present in interfaces. This means you cannot say:

interface INumeric<T>
{
    T operator +(T left, T right);
}
 
struct Vector<T> where T : INumeric<T>
{
    public static T Add(T left, T right)
    {
        return left + right; // INumeric<T> supplies the '+' operator
    }
}

It is possible to do some pretty nasty hacks to get something similar to this on .Net 2.0-3.5 and someone has created a library that implements this (sorry, can't seem to find the link). The code is very interesting, but it's mostly academic - the performance penalty is high and this is the thing you want in a math library.

.Net 4.0 introduces the dynamic keyword, which can be used to simulate this in a much simpler way - but it will also perform worse than a straight Vector3/Vector3d implementation.

Persoanlly, I would *love* to remove all those duplicates in favor of a generic implementation - but this is simply not supported by the .Net runtime.

Edit: read this interview with Anders Hejlsberg (the designer of C#), who explains why generics work like this. It's very interesting.

Edit 2: for a while I thought that F# would solve this issue (due to the awesome type inference of its ancestor, Ocaml), but this is actually a limitation of the runtime not the language running on top of it. As far as I can see, F# has pretty much the same limitations as C# regarding generics.

kvark's picture

Did you perform any tests measuring performance difference between the current implementation and INumeric-based one?
The interface is pretty artificial and can be optimized out on module loading. I'm curious about how smart .net optimizer is.

the Fiddler's picture

The first article I've read on this topic mentioned 7x higher overhead over direct invocation (i.e. INumeric<int> vs int + int). The newer generic operators library (found the link after all!) mentions just a few percent points of overhead.

I haven't done any tests but this might be worth looking into (as long as it holds for both runtimes, at least!)

kvark's picture

I know it's a very serious decision, but I'd prefer flexible generic math over "few percent perfomance gain" even if it's 10-30%. OpenTK is primarily graphical toolkit after all...

the Fiddler's picture

May I suggest writing a very small proof of concept using the generic ops library? Something like Vector3<T> { + - Dot Length } would be enough to judge whether this is worth pursuing further.