Why have a numeric type hierarchy?

The more I think about it, the stranger the concept of having a number type, which is a super-type of integers, rationals and reals seems to be. One thing that comes to mind is the Wittgenstein's concept of class families (where objects are grouped into families, even though neither one is a sub-type of the other, but have some "common property", not necessarily common to all objects in the family). Certainly, not a hierarchy.

And yet, in languages like Java, Common Lisp, Haskell and possibly lots of others there is a concept of a numerical super-type for types like integers, reals, complex etc.

Is there any computer-science-related explanation of existence of such super-type, or is this simply a convenience, which has no deeper meaning?

To some extent it's a convenience. Not all languages have the hierachy you speak of. For instance Ocaml has no such hierarchy and you need to explicitly cast integers to floats. (This is the price you pay for having type inference with principal types in Ocaml.)

But there are other reasons as well. Numeric types are there because we want to do math with computers. In mathematics there are many kinds of numbers, and they are naturally organized according to what structure they carry: the integers form a ring, the rationals form a field, the reals form a complete field, and the complex numbers a complete algebraically closed field. So the mathematical hierarchy gets reflected in the organization of numeric types.

In Haskell there are a number of numeric type classes (Num, Float, Rational, ...) which give the programmer flexibility and modularity. In Haskell it is very easy to switch from one kind of Num to another – as opposed to other software systems where it takes years to switch the numeric data types (consider how big a project it was from 32-bit to 64-bit Windows).

• Here are my two problems with this explanation: 1) You don't mention the supertype, the one I'm curious about. What is a supertype of a ring? A semi-ring? Just a magma (set with a binary operation)? What kind of structure is it? 2) Integers aren't just any ring, they are also a totally ordered set, they also have lots of other properties, such as those described by the fundamental theorem of arithmetic (unique prime factorization) and everything that is derived from it, which doesn't hold in assumed subtypes (rationals, reals etc.) – wvxvw Apr 29 '15 at 16:22
• Having a supertype is also no different from having an Object supertype for instances of data structures; which is essentially a pointer to something that isn't very specific. – Rob Apr 29 '15 at 17:14
• Object-oriented terminology does not correspond easily to the notion of substructure. It does to a point, but you need to be careful with it. But yes, there is an obvious hierarchy of structures that you can emulate object-orientedly. – Andrej Bauer Apr 29 '15 at 17:28
• We use convenient (suggestive) metaphors in computer science all the time. This has the disadvantage of misleading us into confusing literal interpretations sometimes. As Andrej said, we want to model mathematical objects with computers, as much as we want to understand computational objects within some mathematical theoretical framework, but these are two very different things. – André Souza Lemos Apr 29 '15 at 18:01
• @AndréSouzaLemos there's a misunderstanding of what I'm doubtful of. I don't think that the word "number" means anything. I asked this question having a "hidden agenda", viz. I believe that there is no reason such type should exist, and am trying to find a counter-evidence. I'm an undergraduate math student, and I know a little about various kinds of numbers, but I've never heard about any mathematician using some "general numbers set". It's either naturals, integers, reals etc. I'm not aware of any mathematical notion that would be compatible with the one used in programming. – wvxvw Apr 29 '15 at 18:48

If you want to simply have a "number" type, then the compiler (or JIT) would need to prove that a type must be within bounds for a 32-bit integer to use an efficient 32-bit integer representation that the CPU supports, etc. So on one hand, it's an optimization to use machine types. On the other, the types declared can be thought of as assertions on declared variable types (particularly on inputs). Some languages force explicit casts for assignments that will surely lose information (float assign to int).

If you are using float32 instead of int32, the operations (including addition) will no longer be exact.