Int bottom is not safe
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!
In the 32 bit integer arithmetic, -bottom == bottom is true. Any problems?
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.
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?
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.
The choices here seem to be between:
-
Intis an approximation of ℤ (which happens to be implemented with 32-bit ints). We ought to strive fornegate x == xholding iffx == 0, since that's how ℤ acts. -
Intis a representation of 32-bit ints. Hence,negate bottom == bottomis 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