purescript-prelude icon indicating copy to clipboard operation
purescript-prelude copied to clipboard

Int bottom is not safe

Open ursi opened this issue 1 year ago • 5 comments

https://github.com/purescript/purescript-prelude/blob/f4cad0ae8106185c9ab407f43cf9abf05c256af4/src/Data/Bounded.js#L1-L2

The bottom and top values for Int are listed as above. The problem here is that -bottom is greater than top, which means bottom is actually not a safe value for the Ring instance of Int. You can verify for yourself that negate bottom == bottom!

ursi avatar Dec 02 '24 01:12 ursi

In the 32 bit integer arithmetic, -bottom == bottom is true. Any problems?

acple avatar Feb 23 '25 05:02 acple

It makes a possible for abs x to be negative, while still inside the bounds that are supposed to be safe. That is was brought this to my attention in the first place.

ursi avatar Feb 23 '25 22:02 ursi

PureScript Int is a representation of 32 bit signed integer so in my opinion it is even reasonable behavior. However, the behavior of abs bottom for signed integer varies depending on the programming language. Scala(Java), Haskell behaves same as current PureScript. C#, Rust raises an exception. How would you like it to be?

acple avatar Feb 24 '25 01:02 acple

Well, maybe I should just "git gud" and acknowledge this edge case is quite common. But what seemed nice to me was to raise the value by 1 so these behaviours go away. Perhaps the choice of what is best would come down to is what assumption people are going to do more "assumption oriented coding" around - bottom being exactly -2^31, or bottom being safe with abs/negate.

ursi avatar Feb 24 '25 02:02 ursi

The choices here seem to be between:

  1. Int is an approximation of ℤ (which happens to be implemented with 32-bit ints). We ought to strive for negate x == x holding iff x == 0, since that's how ℤ acts.
  2. Int is a representation of 32-bit ints. Hence, negate bottom == bottom is both sensible and expected since it matches spec.

For the standard integer type of a general-purpose programming language like PureScript, I think (1) makes more sense. Int should be ℤ with asterisks — most people using Int just want a reasonably-behaved integer value

Quelklef avatar Feb 24 '25 23:02 Quelklef