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.
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.
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:
The real line is constructed in this order N ā Z ā Q ā R (no cycles).
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.
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.
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ā¦
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 AbstractRationaltype, than this could be done, where Rational <: AbstractRationaland Integer <: AbstractRational. But I believe making Integer<:Rational is impossible.
Edit: Iām not testing these stuff Iām saying, just conjecturing.
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. (Or more simply, because a is a finite set 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.
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.