-
Notifications
You must be signed in to change notification settings - Fork 4.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Force a generic type to support numeric operations #3391
Comments
Well there is where T : struct but it doesn't give you everything you asked for. |
@whoisj :Yes that's just my problem——this only limits "T" is type of struct, however we cannot control whether the struct is of a numeric type that supports Sort, +,-,*,/……operators..... |
And this is very similar to Issue (#3255), however mine is the extension for him——NOT only for simple elements, but customized elements (such as Complex Number, BigInteger……)——These structures are also numeric type, as well. |
I'd prefer to have the more generalised traits (#129). As it would allow to specify the operator the type must have implemented. Also @MaleDong be aware that the "comparison operator" are overloadable those don't have to the meaning of comparison. The contextual meaning of them is down to the type that is implementing them to decide. |
In fact, I suddenly have a thought——To decide whether a number not, Maybe Microsoft can check: Whether a customer has implemented "operator override" such as "+","-","*","/". —— If yes, this can be reguarded as a normal "Number" (fits the generic type's limitation). So Let's just say:
And if the type to support Sort, just let us make it implement IComparable/ICompare ;) |
@MaleDong What is it about a type that makes that type a number? Overriding For example Quaternion which is non-communitive eg Also maintain a list of types that are considered "numeric" in the compiler, means that if say Microsoft implement new numeric type in a library, you have to also update the compiler to include it in the list. Even adding an attribute or interface to the existing "numeric" types is a breaking change. So what is it about a type that makes it numeric? |
I suppose we could look for an |
@whoisj:Your way is quite nice for numeric type. And I'm not sure what you mean by: Instead of always assuming everything will need to be double we have fun things like Vector where T : intrinsic, Matrix : intrinsic, etc. In fact, "T" is a generic type and if you use "int", the result and the intellisense is always "int". |
|
This might have been half-implemented: http://stackoverflow.com/questions/10951392/implementing-arithmetic-in-generics
https://github.com/Microsoft/referencesource/blob/master/mscorlib/system/double.cs#L369 https://twitter.com/migueldeicaza/status/563452383993548801 It seems @davkean knows the details. Suggested title change: "Please finish and release the IArithmetic interface" :) |
I think that the best way to handle this is to have generic type constraints expanded to support specific static (as well as instance?) methods/members of specified signatures. That would cover overloaded operators, including those that affect heterogeneous types. Unfortunately as of now the primitive types don't actually specify those operator methods. They don't have to as the compilers know how to emit proper IL to perform direct addition of the primitive types. But to be usable generically in this fashion they would need the overloaded operator methods otherwise they wouldn't satisfy the constraint. The compiler would then be emitting IL to perform the static method call, which is far from ideal, but the JIT compiler is already smart enough to optimize those calls away. I can imagine that the syntax for such constraints would be absolutely nasty, though. public static T3 GenericAdd<T1, T2, T3>(T1 x, T2 y)
where T1 : struct,
where T2 : struct,
where T3 : struct,
where T1.op_Addition(T1, T2) -> T3
{
return x + y;
} Anything else just doesn't seem like it would fit in with the design of generics, specifically that a single member is emitted with one specific body that can be applied to any set of generic type arguments. Compile-time templates would be more flexible and could solve this problem but would pose other problems. |
I was referring to how developers are forced, today, to develop math libraries against a know type (usually @HaloFour I really like that, though I'd prefer something more elegant. Maybe...
|
Can you show an example function from this maths library (that some mention). They tend to implemented as separate function as each type as it own subtleties, especially at the bit level. |
Well……Thanks for your advices! In order to simpify this problem:
}
|
@MaleDong I do not think you can expect interfaces to support operators. It provides horrible performance. Operators are static methods where as interface methods are instance methods, requiring I think the original discussion about supporting improved |
@whoisj:The reason why I use interface is:
In fact I think:
I know the reason why don't like that because of the conversion of some very basic elements such as "int","double","decimal"……. I think this is the core thing that may be recoded to avoid the "horrible performance". And as what you said, could you please offer us an example (in persudo code) to explain how to use that in details about your thoughts of "where"? Thanks anyway! |
See my proposition for how generic constraints could work. I believe they'd produce optimal code as well given the current compiler logic. Notice that I do not actually care that the operators are performing math of any kind. Instead, I only ask the compiler to constrain the type to one which has defined the
In this case, the I could image this for any of the existing operators. Sure would make classes like vectors easier to write as well as compile time checked (instead of runtime).
|
You are always talking about scalar values. But what happens when we have large arrays and we want to add them? Currently having math operation on two very long arrays works only well with unsafe code. Every other implementation I have tested failed completely. Here I also need to have a pointer on a generic type. It would work well if the numeric type would also support pointers. |
You're assuming that the types can be addressed by unsafe pointers. If the types are references types or contain references, they cannot be. How would you address that? I've proposed a keyword, which could be added to structs to insure that they are |
Registering interest for this feature |
@SirCmpwn there's a "Subscribe" button on the side, which should allow you avoid needlessly posted to get update notifications. |
I am familiar with this button. It doesn't register interest, it subscribes to emails. Sending a notification to the participants revitalizes the discussion and draws renewed attention to the issue for planning. |
This leaves me feeling revitalized for sure! :D |
We are now taking language feature discussion in other repositories:
Features that are under active design or development, or which are "championed" by someone on the language design team, have already been moved either as issues or as checked-in design documents. For example, the proposal in this repo "Proposal: Partial interface implementation a.k.a. Traits" (issue 16139 and a few other issues that request the same thing) are now tracked by the language team at issue 52 in https://github.com/dotnet/csharplang/issues, and there is a draft spec at https://github.com/dotnet/csharplang/blob/master/proposals/default-interface-methods.md and further discussion at issue 288 in https://github.com/dotnet/csharplang/issues. Prototyping of the compiler portion of language features is still tracked here; see, for example, https://github.com/dotnet/roslyn/tree/features/DefaultInterfaceImplementation and issue 17952. In order to facilitate that transition, we have started closing language design discussions from the roslyn repo with a note briefly explaining why. When we are aware of an existing discussion for the feature already in the new repo, we are adding a link to that. But we're not adding new issues to the new repos for existing discussions in this repo that the language design team does not currently envision taking on. Our intent is to eventually close the language design issues in the Roslyn repo and encourage discussion in one of the new repos instead. Our intent is not to shut down discussion on language design - you can still continue discussion on the closed issues if you want - but rather we would like to encourage people to move discussion to where we are more likely to be paying attention (the new repo), or to abandon discussions that are no longer of interest to you. If you happen to notice that one of the closed issues has a relevant issue in the new repo, and we have not added a link to the new issue, we would appreciate you providing a link from the old to the new discussion. That way people who are still interested in the discussion can start paying attention to the new issue. Also, we'd welcome any ideas you might have on how we could better manage the transition. Comments and discussion about closing and/or moving issues should be directed to #18002. Comments and discussion about this issue can take place here or on an issue in the relevant repo. Type classes would support this feature request, and are under consideration at dotnet/csharplang#110 |
Sometimes we have to write a generic Sort way or some special functions with a generic type that must be of a numeric one. However we cannot say something like this:
Though I know that int, long ,double……these basic elements come from ValueType. However I cannot do that because ValueType doesn't directly support operator comparation.
And If I make "T" forced to IComparer, IComparable……, here "T" doesn't ONLY a numeric one, any struct or class implemented this interface, it will have the "capability" to be pushed in.
And what's more——If my generic method/class have "+","-","*","/", only numeric type can do that.
So, it would be better if a generic type can be forced to a numeric one, and supports all kinds of numeric type, the numeric type should also include complicated struct such as "BigInteger".
It would be better if Microsoft can leave some special interfaces, virtual methods for us to create "customized data formation" and it will also be reguarded as "numeric type" (Maybe "Complex Number" is the future)
The text was updated successfully, but these errors were encountered: