Skip to content
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

API Proposal: Generic LINQ Numeric Operators #64031

Open
alrz opened this issue Jan 20, 2022 · 10 comments
Open

API Proposal: Generic LINQ Numeric Operators #64031

alrz opened this issue Jan 20, 2022 · 10 comments
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Linq
Milestone

Comments

@alrz
Copy link
Member

alrz commented Jan 20, 2022

Background and motivation

With the introduction of generic operators it's expected to be able to use LINQ over numeric sequences in a generic manner.
Additionally this can be considered for extensions on other list-like types.

Relates to #63732

API Proposal

namespace System.Linq
{
    public static class Enumerable
    {
        public static T Sum<T>(this IEnumerable<T> source) where T : IAdditionOperators<T, T, T>, IAdditiveIdentity<T, T>;
        public static IEnumerable<T> Range<T, TStep>(T start, T end, TStep step) where ...;
        public static T Min<T>(this IEnumerable<T> source) where T : ..;
        public static T Max<T>(this IEnumerable<T> source) where T : ..;
        // The result value is most likely floating-point. Should it be generic?
        // If so, is it possible for type inference to pick an appropriate type?
        public static T Average<T>(this IEnumerable<T> source) where T : ..;
        // ..
    }
}

API Usage

IEnumerable<T> numericSeq = e;
T sum = numericSeq.Sum();

Alternative Designs

No response

Risks

No response

@alrz alrz added the api-suggestion Early API idea and discussion, it is NOT ready for implementation label Jan 20, 2022
@dotnet-issue-labeler dotnet-issue-labeler bot added area-System.Linq untriaged New issue has not been triaged by the area owner labels Jan 20, 2022
@ghost
Copy link

ghost commented Jan 20, 2022

Tagging subscribers to this area: @dotnet/area-system-linq
See info in area-owners.md if you want to be subscribed.

Issue Details

Background and motivation

With the introduction of generic operators it's expected to be able to use LINQ over numeric sequences in a generic manner.

This relates to #63732 where new constraints are being discussed for T.Min/T.Max etc.

API Proposal

namespace System.Linq
{
    public static class Enumerable
    {
        public static T Sum<T>(this IEnumerable<T> source) where T : IAdditionOperators<T, T, T>;
        public static T Min<T>(this IEnumerable<T> source) where T : ..;
        public static T Max<T>(this IEnumerable<T> source) where T : ..;
        // The result value is most likely floating-point. Should it be generic?
        // If so, is it possible for type inference to pick an appropriate type?
        public static T Average<T>(this IEnumerable<T> source) where T : ..;
        // ..
    }
}

API Usage

IEnumerable<T> numericSeq = e;
T sum = numericSeq.Sum();

Alternative Designs

No response

Risks

No response

Author: alrz
Assignees: -
Labels:

api-suggestion, area-System.Linq, untriaged

Milestone: -

@alrz
Copy link
Member Author

alrz commented Jan 20, 2022

cc @tannergooding

@eiriktsarpalis
Copy link
Member

Echoing @tannergooding's comments in #63732 (comment) wouldn't adding such overloads break overload resolution?

@eiriktsarpalis eiriktsarpalis removed the untriaged New issue has not been triaged by the area owner label Jan 27, 2022
@eiriktsarpalis eiriktsarpalis added this to the Future milestone Jan 27, 2022
@Joe4evr
Copy link
Contributor

Joe4evr commented Jan 27, 2022

wouldn't adding such overloads break overload resolution?

I wouldn't think so. The current overloads (taking IEnumerable<{int|long|float|double|decimal}(?)>) should be more specific than IEnumerable<T> where T : .... The example Tanner gives in that comment concerns an implicit conversion from int to double (because some functions like Sqrt are only available on double so that's what passing an int binds to today), which is allowed for a single value, but an IEnumerable<int> can't implicitly convert to IEnumerable<double> so the <int> case should keep binding to the existing <int> overload even if a generic constrained overload is introduced.

@roji
Copy link
Member

roji commented Jul 10, 2022

I specifically had this need considering how to represent a sum of time intervals operation for translation to SQL with EF Core. A generic Sum method would be perfect for that (TimeSpan would also to implement the appropriate interfaces as well). Of course we'd need queryable versions of these operators.

@Timovzl
Copy link

Timovzl commented Dec 7, 2022

The selector-based overloads (example) seem to be missing from the API proposal.

public static T Sum<TSource, T> (this IEnumerable<TSource> source, Func<TSource, T> selector) 
    where T : IAdditionOperators<T, T, T>, IAdditiveIdentity<T, T>;

Especially for these, perhaps a more descriptive name for T is in order, although I haven't come up with one so far.

@aradalvand
Copy link

aradalvand commented Aug 24, 2024

Why hasn't this been done already? Genuine question. We've had generic math for a few years now. Was there a reason implemented right away?

@roji
Copy link
Member

roji commented Aug 24, 2024

@aradalvand that kind of comment isn't helpful; engineering resources are always limited, and decisions must be made on what's more important. I do agree this issue needs to be done at some point, but given that LINQ operators exist for the major numeric types, it doesn't seem very urgent. This seems to be confirmed by the fact that there are only 30 votes on this issue since it was opened 2.5 years ago.

@aradalvand
Copy link

aradalvand commented Aug 24, 2024

@roji I may have worded that badly; I was just curious to know if there's any other problem currently blocking this or something. Similar to how, for example, there doesn't seem to be a consensus on whether TimeSpan should implement generic math interfaces (see #76225). I was wondering if there was a lingering question mark of that kind here as well, which may be the reason for it not having already been implemented because it seems pretty trivial and obvious on the surface.

@eiriktsarpalis
Copy link
Member

eiriktsarpalis commented Aug 27, 2024

Why hasn't this been done already? Genuine question.

The short answer is resourcing, somebody needs to take the time to prototype generic math methods and importantly examine how new overloads might interact with existing ones in terms of breaking changes etc. It's also not entirely clear to me how generic math (or static abstracts in general) would interact with the IQueryable APIs since they typically invoke their IEnumerable counterparts using reflection. Perhaps this is an already solved problem, but again somebody needs to work this out before we bring the proposal in for review. We're happy to consider community driven prototypes, they typically create momentum for a proposal becoming mature enough and getting prioritized.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Linq
Projects
None yet
Development

No branches or pull requests

6 participants