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

proposal: math: MinOf and MaxOf for generic numeric limits #50019

Open
rogpeppe opened this issue Dec 7, 2021 · 6 comments
Open

proposal: math: MinOf and MaxOf for generic numeric limits #50019

rogpeppe opened this issue Dec 7, 2021 · 6 comments
Labels
Milestone

Comments

@rogpeppe
Copy link
Contributor

@rogpeppe rogpeppe commented Dec 7, 2021

Currently when writing a function involving a generic numeric type, there's no easy way to determine the maximum or minimum possible value of that type, because the math.Min* and math.Max* constants are all type-specific.

I propose that we add the following functions to the math package:

// MinOf returns the minimum possible value of type T.
func MinOf[T contraints.Integer | constraints.Float]() T

// MaxOf returns the maximum possible value of type T.
func MaxOf[T contraints.Integer | constraints.Float]() T

It's currently not possible to write the above functions without using reflection until #45380
is fixed, but here's an approximation:

https://gotipplay.golang.org/p/0i3Wc7i4dJs

@robpike
Copy link
Contributor

@robpike robpike commented Dec 7, 2021

To do this with any kind of efficiency in implementation code, generated code, and execution time seems unlikely. Plus you really want this to be a constant, which won't happen for a function.

So this feels like the wrong approach to me, but the right approach might require some kind of language support if we are to avoid type-asserting from interface{} on the way out.

@robpike
Copy link
Contributor

@robpike robpike commented Dec 7, 2021

P.S. That said, I'm not convinced it's worthwhile to do. I know what it's for but will it show up often enough to need so much mechanism?

@Inuart
Copy link

@Inuart Inuart commented Dec 7, 2021

the right approach might require some kind of language support

IMHO it's essential that somebody writes a crazy idea that everybody can reject. So here I go:

const (
	MaxOf[T number] {
		int: math.MaxInt,
		int8: math.MaxInt8,
		...
	}
	MinOf[T number] {
		int: math.MinInt,
		int8: math.MinInt8,
		...
	}
	...
)

To be used like

func MaxSubSum[T number](arr []T) T {
	best := MinOf[T]
	var current T
	for _, v := range arr {
		current = Max(v, current+v)
		best = Max(best, current)
	}
	return best
}

@rogpeppe
Copy link
Contributor Author

@rogpeppe rogpeppe commented Dec 7, 2021

To do this with any kind of efficiency in implementation code, generated code, and execution time seems unlikely. Plus you really want this to be a constant, which won't happen for a function.

In general we don't allow constants to be derived from type parameters (that way lies madness), but I think it could be done with reasonable efficiency if #45380 was implemented.

In that case, the code might look like this:

func MinOf[T constraints.Integer | constraints.Float]() T {
	switch type T {
	case ~int:
		return math.MinInt
	case ~int8:
		return math.MinInt8
	...
	}
}

I have a feeling it wouldn't take too smart a compiler to implement it as a direct lookup from the dictionary, so not as efficient as a constant (we don't allow constants based on type parameters anyway), but one indirection still isn't too bad.

@renthraysk
Copy link

@renthraysk renthraysk commented Dec 7, 2021

Did play around trying to get something similar, though just for constraints.Integer. With inlining they effectively a constant, though the inliner does assign them a higher inlining cost.

https://gotipplay.golang.org/p/Hw4hnZq3imw

Edit: Typo in code, should not have had the go vet warning.

@robpike
Copy link
Contributor

@robpike robpike commented Dec 7, 2021

In general we don't allow constants to be derived from type parameters (that way lies madness)

What I was getting at, incoherently, was that type parameters might not be the way to do this. The fact that a problem arises because of them does not necessarily mean the solution requires them too.

@ianlancetaylor ianlancetaylor added this to Incoming in Proposals Dec 8, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Proposals
Incoming
Development

No branches or pull requests

5 participants