-2

Currently, generics in C# do not allow any sane way to perform arithmetic. There are awkward workarounds available, but none of them are very neat and all of them reduce performance. According to this interview, an interface with arithmetic types is not possible to implement, and so one such workaround is suggested.

But what you could do is have your Matrix take as an argument a Calculator, and in Calculator, have a method called multiply. You go implement that and you pass it to the Matrix.

Why should I have to tell an advanced programming language how to add and multiply numbers? [Edited due to popular demand]

Why not simply allow a Generic to be restricted to a list of types?

Eg.

class Matrix<T> where T : int,long,float,double

The syntax could of course be different. But the compiler needs only to check that the type is on the list, and that the operators used work on all types, which should be much simpler than the apparently-too-difficult interface suggestion.

Are there any obvious reasons as to why this cannot be implemented?

Mark K
  • 553
  • 4
  • 6
  • 1
    This question answers yours: http://stackoverflow.com/questions/32664/c-generic-constraint-for-only-integers – Locksfree Sep 20 '09 at 00:07
  • No, it does not. It partially answers a series of similar questions, yet the most important one (consider the last "answer" posted) goes unanswered. – Mark K Sep 20 '09 at 00:46
  • 1
    -1: Subjective/Argumentative. "This is incredibly stupid. ... that he even suggests this shows how limited the C# developers are." – Charles Bretana Sep 20 '09 at 01:53
  • Suggestion: it seems like there is too much abstraction in your question, maybe you could add an example of what you want to do and what it should result in. – RBarryYoung Sep 20 '09 at 02:14
  • 2
    Might I suggest that you should phrase this as "why this *should* not be implemented?". As Eric says this can be done by a sufficiently competent developer (though I pity the poor person responsible for making decimal work like the rest) it is, as most Programming Language Design is, about trade offs. Showing you understand this (and some politeness) would have got you a better response... – ShuggyCoUk Sep 21 '09 at 22:11

5 Answers5

20

Why not simply allow a Generic to be restricted to a list of types?

Because then it's not generic. Generics extend the expressivity of the type system as a whole; they're not intended to be a cheap search-and-replace mechanism a la C++ templates.

Are there any obvious reasons as to why this cannot be implemented?

I deny the premise of the question. It could be implemented, if we wanted to work against the basic design principles of generics. Heck, I could implement it in less than a month, I'm quite sure, given the time and budget. However, I have other priorities.

This is incredibly stupid.

Well, when I see Anders on Monday I'll be sure to tell him that Mike K from the internet thinks that his ideas are stupid.

The fact that he even suggests this shows how limited the C# developers are.

Indeed, I am well aware of my personal limitations. I have much to learn still about programming language design and implementation.

I note also that we're also limited by our budget, and by market forces outside our control, as well as many other factors.

And finally, let me take this opportunity to point out that heaping personal insults upon the people who can answer your question works against your goal of getting your question answered. If you're interested in this topic, you might consider reading my short essay on the subject:

http://blogs.msdn.com/ericlippert/archive/2008/02/20/how-to-not-get-a-question-answered.aspx

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • The ironic thing is that I was having a conversation with Anders about exactly this topic couple days ago. The problem of genericized arithmetic is an interesting one and it's not at all clear what the best way to solve it is, or whether we ought to be spending our limited resources on solving it instead of something more important. – Eric Lippert Sep 20 '09 at 06:33
  • Eric: I guess the real question then is, why isn't the type system better at including the native value-types, at least for generics, anyway? That's the real source of the frustration, IMHO. It's very hard to understand how we can have all of this other incredibly complex sophisticated type & inheritance stuff in .NET, but a simple concept like (Integer-->WholeNumbers-->PreciseNumbers-->Numbers) that goes back to the foundations of OO (and Generics as well) can't be included? I am getting tired of implementing my own Complex/Vector/Matrix/etc, Math for every numeric data type in .NET. – RBarryYoung Sep 21 '09 at 16:23
  • Eric: "...whether we ought to be spending our limited resources on solving it instead of something more important." ME: ???!!! I guess we have widely differing views on what's "important". Making native value-types a first-class member of the .Net type and inheritance model strikes me as a pretty darn important thing. – RBarryYoung Sep 21 '09 at 16:32
  • 2
    @RBarryYoung if you write methods like follows T One(U a, V b) { return a + b; } but *manually* insert int, double, byte, long, ulong etc for T, U and V (use the same one in some cases). Once you deal with the compiler errors and warnings look at the decompiled code in reflector. Note how no function calls (the current 'building block' for most generic related behaviour) occur. Indeed note further than actually there is almost no commonality in the IL produced. Much as I would love generic arithmetic I accept that producing a eneral mechanism is *hard*. – ShuggyCoUk Sep 21 '09 at 22:02
  • F# behaves differently in this regard except you will note that it brings with it a different set of hassles (try assigning the value of an int to a float without an explicit cast for example). – ShuggyCoUk Sep 21 '09 at 22:03
  • 2
    And yet every single BASIC compiler from 1964 on has been able to correctly compile polymorphic arithmetic operators down to machine instructions without having to depend on generating function calls. I guess today's compiler technology isn't as advanced as it was in 1964? Or maybe your description is a red herring? – RBarryYoung Sep 22 '09 at 02:52
  • 4
    Native value types *are* first-class members of the .NET type system. They inherit from System.ValueType, which inherits from System.Object. Now, perhaps that inheritance hierarchy does not successfully model numbers *the way you would like*. Not much I can do about that now, unfortunately. On the fortunate side though: there is an increasingly large investment at Microsoft in understanding the needs of the scientific and financial computation community. Hopefully in the future we'll have more tools available to serve this market segment. – Eric Lippert Sep 22 '09 at 15:48
  • Ok, I know this is an old question and I'm picking a fight with a guy who helped design the language in question... but I have an issue with the first sentence here. Sure, templates may be a "find and replace system", but they are powerful. I can trivially implement `Add` via templates. It is not trivial at all in C#. As a systems guy who likes C#, this makes my life difficult. I am currently writing an image processing library (employer will not allow C++) and it is *insanely difficult to perform generic operations on elements of an array, where the type is either `byte`, `ushort`,... – Ed S. Aug 08 '13 at 22:14
  • ...or `float`. It's just way too difficult. I have to leverage a third party generic math library (which is slower than native math) and I also have to sprinkle in `dynamic` here and there. I have tried to remove that last bit completely and have failed. The end result is about 6k fewer lines of code, but this comes at a 4x performance cost. I know templates can be abused, but after working with both languages for a long time I have to admit I much prefer them to C# generics. I thin a special case for numeric types would be well worth it for number crunchers like me. Ok, end rant. – Ed S. Aug 08 '13 at 22:15
2

Generics are not C++ templates. The compiler will only allow operations on generic type parameters that it can verify to be valid for those parameters, because the exact types to be used are not inserted until JIT compilation. C++ does the insertion at compile time, and doesn't care if an operation can be shown to be valid for every possible value of T, as long as it's valid for the specific value of T you're actually using.

Also, a constraint like where T : int makes no sense, because there can not be any types that derive from int, as int is a struct. The only type obeying this constraint would be int itself. If you know your type will always be int, generics become moot.

Joren
  • 14,472
  • 3
  • 50
  • 54
  • 1
    I am aware that they are not C++ templates, and that's not what I want them to be. C++ templates can easily cause runtime errors... With a list of specific types, this should not be possible, as all types can be checked at compile time. As for the second point, no sane person would indeed use "T : int". As you may note, I have listed four types, not one. The entire point would be to reduce code duplication, so I can write a single "generic" matrix rather than one for each type. – Mark K Sep 20 '09 at 00:33
1

I think you are looking for the functionality of a functional programming language in OOP. If that is the case, then use FP.

For example, in Scala, you can replace the operators, so now it can add or multiply your matrix.

This is the case in various languages, but not all OOP languages.

Why should generics be able to do addition when it isn't obvious how to add or multiply? For example, if I have a class of logarithms, then to multiply is just adding the numbers, but, how could a compiler know that?

In C# you can do operator overloading, which should solve the problem you are complaining about: http://msdn.microsoft.com/en-us/library/aa288467%28VS.71%29.aspx

The C# team came to decisions on how to do generics, and it shouldn't handle math as my example above would show, but they did allow for you to help the compiler know how to do the math operations, so blaming them for not asking them for your opinion first is very risky, as the decision has been made, generics are in as they are. It won't be changed now, I believe.

James Black
  • 41,583
  • 10
  • 86
  • 166
  • Have you ever used c++ templates? They make this easy. This is not a problem of the imperative domain, it is a drawback of a design decision. – Ed S. Aug 08 '13 at 22:09
  • @EdS.The question was about C#, which is why I answered it that way. Here is a comparison between C# and templates though, as you are correct templates are more powerful: http://msdn.microsoft.com/en-us/library/c6cyy67b.aspx – James Black Aug 11 '13 at 13:47
1

I would suggest (and excuse my limited knowledge, if this sounds retarded to anyone) to implement both template and generic functionality with their respective keywords. After reading all post (yes all of them) I have to say I agree with both views: Generics should by no means be 'be a cheap search-and-replace mechanism a la C++ templates', however when you have to implement the same function for 2+ types it becomes freaking annoying :P

Perhaps an IArithmetic interface stating the operators that need to be implemented can be used to make constrains a bit tighter?

0

For the very reason that clearly stated in the interview, that adding this kind of support would have added substantial additional complexity for a very minor additional benefit. If you know how to design and write compilers you could argue (in some other forum) as to what degree that is true or false, but not whether it's "stupid" or how "limited" the developers who use the language might be...

Charles Bretana
  • 143,358
  • 22
  • 150
  • 216
  • The interview referred specifically to a specific implementation other than the one I'm describing, which is WHY I described him as limited. There is ALWAYS another way to do something... how do you not see this? – Mark K Sep 20 '09 at 02:26
  • I have removed the offending section. I would hope, in future, that you could focus on the question as a whole, rather than some small subjective section. – Mark K Sep 20 '09 at 02:42
  • @Mike, You should reread the interview, in it, Anders specifically says, in his response that starts "What you are really asking is, what can you say in terms of constraints? ..." And he says, "There's a whole continuum from nothing to grand pattern matching. We think it's too little to say nothing, and the grand pattern matching becomes very complicated, so we're in- between. " – Charles Bretana Sep 21 '09 at 20:23
  • 1
    @Mike, This forum makes a definite and concerted attempt to keep the content focused on objective, technical, substantive topics, so we are perhaps a bit harsh on even minor infractions. It has the major benefit of working. No other forum I've seen has remained as professional, and absent flame-wars and subjective argumentative threads. Downside? Those with thin skins, and a tendency to violate those ideals may get a bit offended. Adapt, and you will find this forum a valuable addition to your toolkit... – Charles Bretana Sep 21 '09 at 20:28