# Numeric types and their relationships

**URL:** https://discourse.julialang.org/t/numeric-types-and-their-relationships/7869
**Category:** General Usage
**Tags:** question, inheritance
**Created:** [December 20, 2017, 4:41am UTC](https://discourse.julialang.org/t/numeric-types-and-their-relationships/7869 "2017-12-20T04:41:54Z")
**Posts on this page:** 15
**Page:** 1

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [December 20, 2017, 4:41am UTC](https://discourse.julialang.org/t/numeric-types-and-their-relationships/7869/1 "2017-12-20T04:41:54Z")

</div>

Suppose I need to define a parametric type with numeric values that are real numbers, but not integers.

Initially I thought of doing something like:

```julia
struct Foo{Integer<:T<:Real} end

```

but I am aware that it has two issues:

1. the syntax `Integer <: T` means a type `T` that can at least hold an integer, so I am not excluding them
2. `Integer`, `AbstractFloat`, `Rational`, and `Irrational` are siblings in the type tree, so asking `Integer <: Rational` returns false

```julia
julia> subtypes(Real)
4-element Array{Union{DataType, UnionAll},1}:
 AbstractFloat
 Integer      
 Irrational   
 Rational  

```

Can you explain the rationale for this design and comment on a possible solution for the original problem?

---

<div class="post-metadata">

### Author: ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)
#### Post date: [December 20, 2017, 5:42am UTC](https://discourse.julialang.org/t/numeric-types-and-their-relationships/7869/2 "2017-12-20T05:42:16Z")

</div>

`Union`?

---

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [December 20, 2017, 5:46am UTC](https://discourse.julialang.org/t/numeric-types-and-their-relationships/7869/3 "2017-12-20T05:46:22Z")

</div>

Thanks @yakir12, `Union` sure solves it. 👍

I am still curious about why the type hierarchy was not chosen so that `Integer <: Rational`, probably a performance bottleneck?

---

<div class="post-metadata">

### Author: ![carstenbauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/carstenbauer/32/4981_2.png) [@carstenbauer](https://discourse.julialang.org/u/carstenbauer)
#### Post date: [December 20, 2017, 6:44am UTC](https://discourse.julialang.org/t/numeric-types-and-their-relationships/7869/4 "2017-12-20T06:44:10Z")

</div>

Unchecked and maybe wrong, but isn’t Rational a particular concrete implementation of a rational number? IIRC it isn’t an abstract type. Please correct me if I’m wrong.

---

<div class="post-metadata">

### Author: ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)
#### Post date: [December 20, 2017, 6:50am UTC](https://discourse.julialang.org/t/numeric-types-and-their-relationships/7869/5 "2017-12-20T06:50:26Z")

</div>

There are a few ways to look at it. One is that implementations of rationals are not a subset of implementations of integers. Another is to ask this question: how would you define rationals without already having defined the integers?

Another view is a bit more philosophical, but fundamentally similar… Although the integers are isomorphic to a subset of the rationals (those with unit denominator), and are conventionally identified with this subset, they are not _the same_ as this subset. If they were, you’d have a circular definition of the integers since you have to define the rationals in terms of the integers. This is similar to the situation in a computer implementation: you define rationals in terms of integers, so the integers cannot be a subtype of rationals.

---

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [December 20, 2017, 7:30am UTC](https://discourse.julialang.org/t/numeric-types-and-their-relationships/7869/6 "2017-12-20T07:30:34Z")

</div>

I get the implementation argument, but the mathematical one, I disagree. The rationals are defined in terms of the integers, and there is no circular argument:

> **[Rational number](https://en.wikipedia.org/wiki/Rational_number)**
>
> In mathematics, a rational number is a number that can be expressed as the quotient or fraction 
>   
>     
>       
>         
>           
>             
> p
> q
>             
>           
>         
>       
>     
> {\\displaystyle {\\tfrac {p}{q}}}
>   
> of two integers, a numerator p and a non-zero denominator q. For example, 
>   
>     
>       
>         
>           
>             
>               
> −
> 3
>               
> 7
>             
>           
> A ...

The real line is constructed in this order N → Z → Q → R (no cycles).

---

<div class="post-metadata">

### Author: ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)
#### Post date: [December 20, 2017, 8:54am UTC](https://discourse.julialang.org/t/numeric-types-and-their-relationships/7869/7 "2017-12-20T08:54:55Z")

</div>

Yes, that’s exactly what I’m saying – the integers are defined before the rationals, so the integers cannot actually be part of the rationals, just identified with a subset of them.

---

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [December 20, 2017, 4:00pm UTC](https://discourse.julialang.org/t/numeric-types-and-their-relationships/7869/9 "2017-12-20T16:00:03Z")

</div>

I don’t understand your explanation, what you mean by part? Exactly because one can identify the integers with an equivalent subset of the rationals, I don’t see how the Julia `Integer <: Rational` operation should return false.

If there are practical implementation difficulties, then that is another history.

---

<div class="post-metadata">

### Author: ![John\_Gibson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/john_gibson/32/5321_2.png) [@John\_Gibson](https://discourse.julialang.org/u/John_Gibson)
#### Post date: [December 20, 2017, 4:34pm UTC](https://discourse.julialang.org/t/numeric-types-and-their-relationships/7869/10 "2017-12-20T16:34:23Z")

</div>

`<:` is the subtype operator, not the subset operator. `Integer <: Rational` returns false because `Integer` is not a subtype of `Rational`.

```julia
help?> <:
search: <:

  <:(T1, T2)

  Subtype operator, equivalent to issubtype(T1, T2).

  julia> Float64 <: AbstractFloat
  true
  
  julia> Vector{Int} <: AbstractArray
  true

```

---

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [December 20, 2017, 4:41pm UTC](https://discourse.julialang.org/t/numeric-types-and-their-relationships/7869/11 "2017-12-20T16:41:13Z")

</div>

Got it @John_Gibson, I was confused with the operation, makes sense now.

---

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [December 20, 2017, 4:43pm UTC](https://discourse.julialang.org/t/numeric-types-and-their-relationships/7869/12 "2017-12-20T16:43:54Z")

</div>

Actually, I am still confused, why is Integer not a subtype of Rational? Given an object of type Int, wouldn’t be ideal to say it is also a Rational with denominator 1?

I think I am seeing the cycle argument issue that @StefanKarpinski mentioned with defining one type in terms of the other…

---

<div class="post-metadata">

### Author: ![favba](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/favba/32/2735_2.png) [@favba](https://discourse.julialang.org/u/favba)
#### Post date: [December 20, 2017, 4:52pm UTC](https://discourse.julialang.org/t/numeric-types-and-their-relationships/7869/13 "2017-12-20T16:52:25Z")

</div>

I believe the `Rational` type is a `Union` type of the parametric type `Rational{T} where T<:Integer`, so it is not possible to make `Integer` a subtype of it.

Maybe, if there was a `AbstractRational`type, than this could be done, where `Rational <: AbstractRational`and `Integer <: AbstractRational`. But I believe making `Integer<:Rational` is impossible.

Edit: I’m not testing these stuff I’m saying, just conjecturing.

---

<div class="post-metadata">

### Author: ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)
#### Post date: [December 20, 2017, 4:56pm UTC](https://discourse.julialang.org/t/numeric-types-and-their-relationships/7869/14 "2017-12-20T16:56:36Z")

</div>

Despite mathematical convenience, being “isomorphic to” is not the same as being “identical to”. Mathematically, the rational numbers are _defined_ as the equivalence classes of pairs of integers (a,b) where b \neq 0 under the equivalence relation

\qquad (a, b) \equiv (c, d) \iff ad = bc

The rational numbers with representatives (a,1) form a subset of this set of classes that are isomorphic to the ring of integers, but they are not formally the same objects, they just behave the same. In symbols: a \neq \left[(a,1)\right]\_\equiv. These cannot be the same object because of the [axiom of regularity](https://en.wikipedia.org/wiki/Axiom_of_regularity). (Or more simply, because `a` is a [finite set](https://en.wikipedia.org/wiki/Set-theoretic_definition_of_natural_numbers#Definition_as_von_Neumann_ordinals) whereas the equivalence class \left[(a,1)\right]\_\equiv is an infinite set of pairs of integers, so they’re quite different objects.)

When mathematicians consider the integers to be a “subset” of the rationals, they are not talking about the same set of integers that were used in the above definition, they are talking about the subset of rationals that behave like those “original integers”. For humans, this distinction is easy to gloss over and we transparently switch between which meaning of “the integers” we’re talking about without even realizing it. But they are very much distinct mathematical entities.

In computers, we have to do a similar construction and for the same reason, the integers which the rationals are defined in terms of cannot logically be a subset of the rationals that they are used to define. If this doesn’t make sense to you, that’s fine (I’m not going to argue the point further), but my point is that even mathematically, the integers from which the rationals are constructed are not a subset of the rationals, they are merely isomorphic to a subset of the rationals. In Julia, we model this kind of isomorphism between structurally different objects by just giving them compatible behaviors, rather than with a type relation.

---

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [December 20, 2017, 4:59pm UTC](https://discourse.julialang.org/t/numeric-types-and-their-relationships/7869/15 "2017-12-20T16:59:27Z")

</div>

It makes total sense, I see the difference and its implications.

---

<div class="post-metadata">

### Author: ![ScottPJones](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scottpjones/32/146_2.png) [@ScottPJones](https://discourse.julialang.org/u/ScottPJones)
#### Post date: [December 21, 2017, 1:20am UTC](https://discourse.julialang.org/t/numeric-types-and-their-relationships/7869/16 "2017-12-21T01:20:58Z")

</div>

I wonder if using traits might be better, because, unlike subtyping, you can add other types and traits later.  
It’s such a powerful thing in Julia, once you get the hang of it (I do wish some syntax for traits like we had discussed at JuliaCon 2016 had made it into the feature freeze for v0.7!).  
Instead of a hierarchy, you’d use traits for whether a numeric type represented rational or irrational, signed integer, unsigned integer, binary float, or decimal float, fixed or arbitrary precision, etc.
