-
-
Notifications
You must be signed in to change notification settings - Fork 58
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
Make an RFC for preventing max and min from contaminating exact numbers #112
Comments
I think that silently throwing away information about inexactness should never be the default behavior. If contamination has occurred then that is something that needs to be dealt with explicitly. Unsignaled loss of precision (i.e. implicitly converting a inexact number to an exact number) can be extremely dangerous and IIRC was one of the points of discussion during the original development of the numerical section of Scheme standard. I'm not saying that the suggestion on the table is a bad idea, but the consequences of such a change would need be be very carefully considered across a wide range of use cases. EDIT: I see I missed a slight subtlety, however, let me give a more annoying example. |
I think (min x y)
case 1, x < y: x
case 2, y < x: y
case 3, else x = y or incomparable: "contaminate" with inexactness as the current version does The reason I think this is better than > (argmin identity (list 1.0 1))
1.0
> (argmin identity (list 1 1.0)) ; this use of argmin depends on order
1
> (min 1.0 1)
1.0
> (min 1 1.0) ; the min function should not depend on order
1.0 |
Is it possible to add
Another interesting case to remember:
Also
An alternative to use
|
Getting the number +inf.0 as a result means there "a number larger than As I understand Sorawee, an exact version of infinity, say, -inf would work as A simpler, backwards compatible solution is to introduce a second set of min/max functions, Another backwards compatible solution is (copying Gus's idea) to choose two values, |
I prefer
i.e. |
Use of |
The current behavior is arguably correct in its own way. Suppose we were computing In the bigger picture, the best choice of identity element for Racket's numeric tower isn't conducive to talking about "all the others," because it's already extended with so many different things. If it's never extended again, then So users who do want to deal with universal properties like "the one number that's less than all the others" will really have a better time if they use types which are less extensible than Racket's "number" type. Once they're willing to take that approach, it's not hard to define specialized functions like |
Just a side comment. Currently Racket also gives:
Even with float propagation, the first result in particular slightly disturbing:
|
Comparisons should not be based on guesses but on rules. Rules make computation predictable, predictability reduces surprise and bugs. If the first number ought to be 1. because some calculation has numerical errors, then the issue is with the upstream calculation, not with |
Floating point numbers are a certain system of rules for guessing. Someone who doesn't consider any numerical error to be acceptable for their use case shouldn't use floats, and someone who does might find Floating-point numbers unfortunately carry no information about the amount of precision they have. When Maybe the caller knows that the |
@Metaxal: I just tried with the float-float case, and I got
I expected @sorawee: Your initial use case just bite me. I need something like
and it was very handily to use |
(max 1.0 2)
results in2.0
. I propose that it should return2
.For me, I mostly use
max
andmin
when I write dynamic programming algorithms. The initial value in these algorithms is usually+inf.0
or-inf.0
. But then(min +inf.0 3)
results in3.0
, which is a real hassle. It also causescheck-equal?
andequal?
to fail.Currently, I have been using
(define (max . xs) (argmax identity xs))
to workaround this problem.The text was updated successfully, but these errors were encountered: