
I was wondering if someone could give me some references to when and why the choice was made to default integral numerical literals to Integer rather than to Int in Haskell. Also, if you are aware of similar discussions in other languages. I'd like to use this information to make an analogous case for defaulting real numerical literals (well, the literals are likely to be in scientific notation, i.e., floating point) to some data type of computable reals rather than to floating point Double. Jens

Jens Blanck
I was wondering if someone could give me some references to when and why the choice was made to default integral numerical literals to Integer rather than to Int in Haskell.
My guess is precision: some numeric calculations (even doing a round on some Double values) will be too large for Int values (at least on 32bit). Note that unlike Python, etc. Haskell doesn't allow functions like round to choose between Int and Integer (which is equivalent to the long type in Python, etc.).
I'd like to use this information to make an analogous case for defaulting real numerical literals (well, the literals are likely to be in scientific notation, i.e., floating point) to some data type of computable reals rather than to floating point Double.
The difference here is performance: under the hood, Integer values which can be expressed as an Int _are_ stored as an Int (IIUC anyway); however computable reals are almost always inefficient. -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com

On 1 April 2010 10:53, Ivan Lazar Miljenovic
I was wondering if someone could give me some references to when and why
Jens Blanck
writes: the choice was made to default integral numerical literals to Integer rather than to Int in Haskell.
My guess is precision: some numeric calculations (even doing a round on some Double values) will be too large for Int values (at least on 32bit). Note that unlike Python, etc. Haskell doesn't allow functions like round to choose between Int and Integer (which is equivalent to the long type in Python, etc.).
Ints have perfect precision as long as you remember that it implements modulo arithmetic for some power of 2. I was hoping that the reason would be that Integers give more users what they expect, namely integers, instead of something where you can add two positive numbers and wind up with a negative number. The type for round is (Fractional a, Integral b) => a -> b, so that can used to give Integer or Int as you like.
I'd like to use this information to make an analogous case for defaulting
real numerical literals (well, the literals are likely to be in scientific notation, i.e., floating point) to some data type of computable reals rather than to floating point Double.
The difference here is performance: under the hood, Integer values which can be expressed as an Int _are_ stored as an Int (IIUC anyway); however computable reals are almost always inefficient.
Yes, the cost for computable reals will be an order of magnitude or possibly two for well-behaved computations. For not well-behaved problems it will be much worse, but it won't return nonsense either. Also consider that the difference between Integers and unboxed Ints is also quite big. I'll happily to take the hit.

Jens Blanck
On 1 April 2010 10:53, Ivan Lazar Miljenovic
wrote: Jens Blanck
writes: I was wondering if someone could give me some references to when and why the choice was made to default integral numerical literals to Integer rather than to Int in Haskell.
Seems to have been in 1998. I don't have a complete archive of the discussion, though, and I don't know where to find the Haskell 98 committee minutes on-line.
My guess is precision: some numeric calculations (even doing a round on some Double values) will be too large for Int values (at least on 32bit). Note that unlike Python, etc. Haskell doesn't allow functions like round to choose between Int and Integer (which is equivalent to the long type in Python, etc.).
Ints have perfect precision as long as you remember that it implements modulo arithmetic for some power of 2. I was hoping that the reason would be that Integers give more users what they expect, namely integers, instead of something where you can add two positive numbers and wind up with a negative number.
As I interpret the part of the discussion I have on file, there are two reasons: (1) as you hoped, because Integers are what people "expect": reasoning on Integers is more reliable -- you can't do induction on Int, for example, and people don't generally try to prove that they've implemented f x = the_f_they_originally_wanted x `mod` 2^32 (2) good language design. One of the things I've repeated over the years is that Int doesn't have to be part of the language (it's just another peculiar type that should be defined in a library) but Integer does, because without it there's no way to specify the meaning of an Integral constant¹. Jón [1] This isn't quite true; using subtyping one could make Integral constants into [Digit] and leave the conversion to the point where overloading is resolved, but that's a much longer story. -- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html (updated 2009-01-31)

The cost factor of Integer vs Int is far, far smaller than the factor
between computable reals vs Double.
On Thu, Apr 1, 2010 at 6:33 PM, Jens Blanck
Yes, the cost for computable reals will be an order of magnitude or possibly two for well-behaved computations. For not well-behaved problems it will be much worse, but it won't return nonsense either. Also consider that the difference between Integers and unboxed Ints is also quite big. I'll happily to take the hit.

Thanks for your replies. In particular to Jon for the reference to the Haskell 98 standard and the comment about language design. If anyone has further references to Haskell 98 or Erlang, I'm still interested. Regarding cost, I do see the difference in factors (Integer - Int, and computable real - Double) as being relevant, but not necessarily a show-stopper. Regarding co-semidecidable equality, I'll just note that any numerical analyst knows that you're not allowed to compare for equality in Double either. Rationals or the real algebraic closure do have decidable equality but are, as far as I know, even more costly to compute with. Thanks, Jens

On Thu, Apr 1, 2010 at 11:27 AM, Jens Blanck
I was wondering if someone could give me some references to when and why the choice was made to default integral numerical literals to Integer rather than to Int in Haskell. Also, if you are aware of similar discussions in other languages.
There is one for Erlang I am aware of. Unfortunately I can't remember where I have read it, so it will have to come off of my head rather than by correct citation. I think it was Joe Armstrong who mused over the idea of having integers of arbitrary size. The argument is that a bug in software due to overflow can be very costly to fix in big installations. As such, it is better to avoid problems by using, essentially, Integer as the default integer type.

On Thu, Apr 1, 2010 at 5:27 AM, Jens Blanck
I was wondering if someone could give me some references to when and why the choice was made to default integral numerical literals to Integer rather than to Int in Haskell. Also, if you are aware of similar discussions in other languages. I'd like to use this information to make an analogous case for defaulting real numerical literals (well, the literals are likely to be in scientific notation, i.e., floating point) to some data type of computable reals rather than to floating point Double.
Integer (and Rational) have decidable equality testing. I don't think
the same can be said for computable reals. (Does pi == pi? How about 2
* asin 1?)
--
Dave Menendez

Jens Blanck schrieb:
I was wondering if someone could give me some references to when and why the choice was made to default integral numerical literals to Integer rather than to Int in Haskell. Also, if you are aware of similar discussions in other languages. I think type defaulting is only an issue for GHCi because in compiled code you should not let the compiler and reader of your code guess the type. GHC -Wall warns about uses of default types.
I'd like to use this information to make an analogous case for defaulting real numerical literals (well, the literals are likely to be in scientific notation, i.e., floating point) to some data type of computable reals rather than to floating point Double. You might be interested in http://www.haskell.org/haskellwiki/Libraries_and_tools/Mathematics#Real_and_...
participants (7)
-
David Menendez
-
Henning Thielemann
-
Ivan Lazar Miljenovic
-
Jens Blanck
-
Jesper Louis Andersen
-
Jon Fairbairn
-
Lennart Augustsson