Whereas Integer.MIN_VALUE is the value of its type that is less than all others, Float.MIN_VALUE and Double.MIN_VALUE are something else: the smallest representable value *greater than zero*.
The existing names are plainly incorrect. Worse, they have an obvious-but-wrong interpretation that is strong enough that the user isn't even moved to go look up the documentation; they don't even have enough cause to *suspect* that the value might not be what it says.
Google's analysis of their large codebase revealed that approximately one-third of all usages of these constants were in error (!). And this does not count the bugs that were already found at some stage (perhaps in production), but already exacted their toll.
Though deprecating a thirty-year-old constant is not something we should do every day, this seems like one of the most clear and compelling arguments for doing just that that I can imagine.
Details:
* The obvious natural choice for the new constants' name is either MIN_POSITIVE_VALUE or MIN_POSITIVE. It's hard to think of a next option. It is correct and consistent, and groups/completes well alongside the other constants. (An alternative like EPSILON would be cute, but not discoverable, beyond being something of a misinterpretation of how epsilon is conventionally used in math.)
* As for including _VALUE in the name or not, it feels appropriate, but I note that MIN_NORMAL opted *not* to. That might force our hand here. Here's a ret-conned consistency argument: since all constants are "values", it's redundant to call them as such; but MIN is a special case that would feel too short and "bare" without it. Sensible?
* Then what about a constant for the *real* MIN_VALUE, and a MAX_NEGATIVE constant for symmetry? But in these cases, users already just negate the existing constants. These classes generally rely on that symmetry, with NEGATIVE_INFINITY being the lone anomaly; this is explicitly different from the integral classes which don't _have_ that symmetry in the first place. In short, even if we did want to round out the set of constants, there is no reason to bundle that change with this one anyway. (Also, MAX_NEGATIVE can be a bit twisty to think about, and some users might accidentally read it as "maximally far from zero"...)
* What to do with MIN_VALUE, then? I think deprecation-not-for-removal seems appropriate. Any nuisance it causes to users seems justifiable by the probability that we are helping them find bugs. On net balance we think this deprecation would be doing them a service.
* Discoverability factor? I'd rate it high, due to the deprecation and because the MIN_ prefix has the right grouping and completion properties.
What are the arguments against this change? I am aware of one, which is that it is uncomfortable to deprecate something that has been stable for so long. I don't currently know a more concrete form of this point.
And: this particular issue is especially well-timed as we are beginning to investigate previewing *new* floating-point types, in the form of "pre-value-class" library classes. If we do nothing now, we will be forced to either be *inconsistent* with the well-known types, or have to actively *repeat* a known decades-old naming error in the new APIs, both of which are sadmaking. By addressing this issue now, we'd get to have both correctness and consistency at the same time.
Thanks to our Google friends for this suggestion: https://mail.openjdk.org/pipermail/core-libs-dev/2024-December/136535.html
The existing names are plainly incorrect. Worse, they have an obvious-but-wrong interpretation that is strong enough that the user isn't even moved to go look up the documentation; they don't even have enough cause to *suspect* that the value might not be what it says.
Google's analysis of their large codebase revealed that approximately one-third of all usages of these constants were in error (!). And this does not count the bugs that were already found at some stage (perhaps in production), but already exacted their toll.
Though deprecating a thirty-year-old constant is not something we should do every day, this seems like one of the most clear and compelling arguments for doing just that that I can imagine.
Details:
* The obvious natural choice for the new constants' name is either MIN_POSITIVE_VALUE or MIN_POSITIVE. It's hard to think of a next option. It is correct and consistent, and groups/completes well alongside the other constants. (An alternative like EPSILON would be cute, but not discoverable, beyond being something of a misinterpretation of how epsilon is conventionally used in math.)
* As for including _VALUE in the name or not, it feels appropriate, but I note that MIN_NORMAL opted *not* to. That might force our hand here. Here's a ret-conned consistency argument: since all constants are "values", it's redundant to call them as such; but MIN is a special case that would feel too short and "bare" without it. Sensible?
* Then what about a constant for the *real* MIN_VALUE, and a MAX_NEGATIVE constant for symmetry? But in these cases, users already just negate the existing constants. These classes generally rely on that symmetry, with NEGATIVE_INFINITY being the lone anomaly; this is explicitly different from the integral classes which don't _have_ that symmetry in the first place. In short, even if we did want to round out the set of constants, there is no reason to bundle that change with this one anyway. (Also, MAX_NEGATIVE can be a bit twisty to think about, and some users might accidentally read it as "maximally far from zero"...)
* What to do with MIN_VALUE, then? I think deprecation-not-for-removal seems appropriate. Any nuisance it causes to users seems justifiable by the probability that we are helping them find bugs. On net balance we think this deprecation would be doing them a service.
* Discoverability factor? I'd rate it high, due to the deprecation and because the MIN_ prefix has the right grouping and completion properties.
What are the arguments against this change? I am aware of one, which is that it is uncomfortable to deprecate something that has been stable for so long. I don't currently know a more concrete form of this point.
And: this particular issue is especially well-timed as we are beginning to investigate previewing *new* floating-point types, in the form of "pre-value-class" library classes. If we do nothing now, we will be forced to either be *inconsistent* with the well-known types, or have to actively *repeat* a known decades-old naming error in the new APIs, both of which are sadmaking. By addressing this issue now, we'd get to have both correctness and consistency at the same time.
Thanks to our Google friends for this suggestion: https://mail.openjdk.org/pipermail/core-libs-dev/2024-December/136535.html