# Really? Not irrational?

**URL:** <https://discourse.julialang.org/t/really-not-irrational/9485>\
**Category:** General Usage\
**Created:** [March 4, 2018, 10:42am UTC](https://discourse.julialang.org/t/really-not-irrational/9485 "2018-03-04T10:42:18Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![tk3369](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tk3369/32/2824_2.png) [@tk3369](https://discourse.julialang.org/u/tk3369)\
**Post date:** [March 4, 2018, 10:42am UTC](https://discourse.julialang.org/t/really-not-irrational/9485/1 "2018-03-04T10:42:18Z")

</div>

I told my 13-year old girl that Julia has both rational and irrational types. How we started this conversation is a different story 🙂

As I showed off how it works in the REPL, she pointed out that it’s wrong to have `sqrt(2)` not being an irrational type… common sense tells us that a number is either rational or irrational but cannot be neither. 😅

I understand that a value can only has one type and it makes perfect sense to put it under `AbstractFloat`. However, does this behavior bother anyone? Should rational/irrational really be a characteristic of a number a type rather than a type, hence we just have various supporting functions around them?

```julia
julia> sqrt(2) isa Irrational
false

julia> sqrt(2) isa Rational
false

julia> sqrt(2) isa Real
true

julia> sqrt(2) isa AbstractFloat
true

```

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [March 4, 2018, 10:48am UTC](https://discourse.julialang.org/t/really-not-irrational/9485/2 "2018-03-04T10:48:30Z")

</div>

> [@tk3369](#):
>
> However, does this behavior bother anyone?

`sqrt` is not equivalent to the mathematical definition of \sqrt{}, it is an approximation of the latter in the relevant subset of numbers (in the case of `sqrt(::Int)`, the set of `Float64`). Most computer languages (except for CAS) work this way.

`Irrational` is a nice addition to the standard floating point menagerie, for representing irrational values “exactly”, for some operations. See [`mathconstants.jl`](https://github.com/JuliaLang/julia/blob/705fb65910e3189a35c92523ab90f73988fc95f8/base/mathconstants.jl) for details.

---

<div class="post-metadata">

**Author:** ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)\
**Post date:** [March 4, 2018, 12:25pm UTC](https://discourse.julialang.org/t/really-not-irrational/9485/3 "2018-03-04T12:25:08Z")

</div>

AFAIK `Irrational` represents a computable number, in the original sense: It is a piece of code that can compute successive approximations (including a-posteriori bounds). Now, arithmetic on computable numbers is nice in math but kinda bad in practice (equality is undecidable!). Hence, `sqrt(2)` is an eagerly evaluated approximation in julia.

I would not argue against a rename of `Irrational` to `LazyComputableReal` (which eagerly approximates on arithmetic), though (or did I misunderstand the intention behind `Irrational`?).

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [March 4, 2018, 12:42pm UTC](https://discourse.julialang.org/t/really-not-irrational/9485/4 "2018-03-04T12:42:44Z")

</div>

Arithmetic in programming languages is typically implemented using [Floating-point arithmetic - Wikipedia](https://en.wikipedia.org/wiki/Floating-point_arithmetic). Assuming that this carries over 1-to-1 to ideal mathematical structures will not end well.

In this specific case, the type `Irrational`s purpose is simply to lift an irrational number (which can’t be represented in the standard numerical types) to the type domain where it can be dispatched on.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [March 4, 2018, 3:30pm UTC](https://discourse.julialang.org/t/really-not-irrational/9485/5 "2018-03-04T15:30:10Z")

</div>

> [@foobar\_lv2](#):
>
> or did I misunderstand the intention behind `Irrational`?

I think it is possible that you might have. AFAICT `Irrational` is not lazily computed at all, eg [`π` is just `3.14159265358979323846`](https://github.com/JuliaLang/julia/blob/705fb65910e3189a35c92523ab90f73988fc95f8/base/mathconstants.jl#L13). I think that their advantage is that certain operations are exact, eg \log(e) = 1, [see here](https://github.com/JuliaLang/julia/blob/705fb65910e3189a35c92523ab90f73988fc95f8/base/mathconstants.jl#L90).

---

<div class="post-metadata">

**Author:** ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)\
**Post date:** [March 4, 2018, 3:42pm UTC](https://discourse.julialang.org/t/really-not-irrational/9485/6 "2018-03-04T15:42:27Z")

</div>

Oh. I did not look at the detailed implementation but was convinced by

```julia
f(x, prec1,prec2)= BigFloat(x, prec1)-BigFloat(x,prec2)
@show f(pi+0.0, 100, 105);
#f(pi + 0.0, 100, 105) = 0.0
@show f(pi, 100, 105);
#f(pi, 100, 105) = -1.97215226305252951352932141320696557418301608777255751192569732666015625e-31

```

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [March 4, 2018, 4:22pm UTC](https://discourse.julialang.org/t/really-not-irrational/9485/7 "2018-03-04T16:22:28Z")

</div>

> [@Tamas\_Papp](#):
>
> π is just 3.14159265358979323846

It’s not, that’s just the float64 approximation and doesn’t really need to be there…

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [March 4, 2018, 5:16pm UTC](https://discourse.julialang.org/t/really-not-irrational/9485/8 "2018-03-04T17:16:27Z")

</div>

It’s much more clever than that – it’s an object that really does represent the true irrational and “knows its value adaptively” relative to its local context. E.g.

```julia
julia> Float64(pi, RoundDown)
3.141592653589793

julia> Float64(pi, RoundUp)
3.1415926535897936

julia> BigFloat(pi, RoundUp)
3.141592653589793238462643383279502884197169399375105820974944592307816406286233

julia> BigFloat(pi, RoundDown)
3.141592653589793238462643383279502884197169399375105820974944592307816406286198

julia> 1.0*pi
3.141592653589793

julia> big(1.0)*pi
3.141592653589793238462643383279502884197169399375105820974944592307816406286198

```

(The last one uses a `BigFloat` approximation to `pi`.)

In principal it’s possible to add new Irrational objects in one’s own code. Steven Johnson had a proposal at some point.

---

<div class="post-metadata">

**Author:** ![Non-Contradiction](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/non-contradiction/32/2208_2.png) [@Non-Contradiction](https://discourse.julialang.org/u/Non-Contradiction)\
**Post date:** [March 4, 2018, 5:28pm UTC](https://discourse.julialang.org/t/really-not-irrational/9485/9 "2018-03-04T17:28:26Z")

</div>

I think to talk about whether a Float64 number to be rational or not is meaningless, so the current behaviour is ok. Float64 is just an approximation of real number with some precision restriction. Different real numbers can have same Float64 number corresponding to it. Mathematically, you can use both rational/irrational number to approximate both rational/irrational number with whatever precision you want, so it is useless to find out whether the approximation is rational or irrational.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [March 4, 2018, 5:49pm UTC](https://discourse.julialang.org/t/really-not-irrational/9485/10 "2018-03-04T17:49:29Z")

</div>

> [@dpsanders](#):
>
> It’s much more clever than that

Thanks for the correction, I see that it is [using MPFR](https://github.com/JuliaLang/julia/blob/705fb65910e3189a35c92523ab90f73988fc95f8/base/irrationals.jl#L133).

---

<div class="post-metadata">

**Author:** ![nalimilan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nalimilan/32/147_2.png) [@nalimilan](https://discourse.julialang.org/u/nalimilan)\
**Post date:** [March 4, 2018, 6:41pm UTC](https://discourse.julialang.org/t/really-not-irrational/9485/11 "2018-03-04T18:41:00Z")

</div>

I’d say the confusing fact is that e.g. `1 isa Rational` is `false`. Indeed, contrary to what one might expect, `Rational` is not the abstract supertype of all kinds of rationals, but a concrete type representing rationals in one specific way. To correspond more closely to math terminology, that type would have to be called `Fraction` or something like that.

---

<div class="post-metadata">

**Author:** ![Ralph\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ralph_smith/32/10344_2.png) [@Ralph\_Smith](https://discourse.julialang.org/u/Ralph_Smith)\
**Post date:** [March 4, 2018, 6:53pm UTC](https://discourse.julialang.org/t/really-not-irrational/9485/12 "2018-03-04T18:53:04Z")

</div>

> [@dpsanders](#):
>
> It’s much more clever than that – it’s an object that really does represent the true irrational

But only in a very restricted sense (unlimited context-appropriate precision with isolated special methods):

```julia
julia> typeof(ℯ)
Irrational{:ℯ}

julia> typeof(log(ℯ))
Int64

julia> typeof(log(ℯ^2))
Float64

julia> typeof(π*π)
Float64

```

Someone might build a nice number theory engine using Julia, but Base + the standard library is practical for us number-crunchers instead.

---

<div class="post-metadata">

**Author:** ![chakravala](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chakravala/32/6832_2.png) [@chakravala](https://discourse.julialang.org/u/chakravala)\
**Post date:** [March 4, 2018, 7:35pm UTC](https://discourse.julialang.org/t/really-not-irrational/9485/13 "2018-03-04T19:35:11Z")

</div>

Julia is not a formal mathematical language, I realized that it falls far short from that when I realized I can’t define my own operator characters. Julia is a programming language, it does not carry a 1-1 correspondence to mathematical vernacular, although it gets very close to it. What I realized though is that Julia will never be able to used as a formal mathematical vernacular due to limitations in programming language design, pure mathematics is much more general, abstract, and has far more complicated context sensitive grammar than any useful programming language could attain. But it is neat that Julia is able to come closer than others, but I think languages like `agda` or some theorem provers get even closer than julia is.

---

<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:** [March 4, 2018, 11:48pm UTC](https://discourse.julialang.org/t/really-not-irrational/9485/14 "2018-03-04T23:48:48Z")

</div>

> [@chakravala](#):
>
> I realized that it falls far short from that when I realized I can’t define my own operator characters.

You cannot add new ones to the parser, but I think that most every Unicode character that could be used as an operator _can_ be defined as one.  
I counted at _least_ 552 operators available in v0.7, with different precedence levels.

For example:

```julia
julia> ⊗(a,b) = println("operate on $a and $b")
⊗ (generic function with 1 method)

julia> 123 ⊗ 456
operate on 123 and 456

```

---

<div class="post-metadata">

**Author:** ![chakravala](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chakravala/32/6832_2.png) [@chakravala](https://discourse.julialang.org/u/chakravala)\
**Post date:** [March 4, 2018, 11:57pm UTC](https://discourse.julialang.org/t/really-not-irrational/9485/15 "2018-03-04T23:57:37Z")

</div>

> [@ScottPJones](#):
>
> You cannot add new ones to the parser, but I think that most every Unicode character that could be used as an operator can be defined as one.

Yes, I’m aware, I’ve added a character to that list already, but was not able to get all the characters I wanted to use approved, since there is some context-sensitive ambiguity with how some symbols should be interpreted.

Also, the order of operations is entirely pre-set in the list of characters, so if I wanted to use an operator with a different order of operations precedence, I can’t do it, since the Julia developers want to ensure compatibility for all users. However, some languages like `agda` are more flexible in that regard.

For a Mathematician, this is a limitation, since we like to define operations and symbols on a whim, many symbols can have completely different interpretations and order of operations in different contexts, for a pure mathematician at least, so Julia is not able to handle that situation.

But this is getting a bit off topic.

---

<div class="post-metadata">

**Author:** ![simonbyrne](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simonbyrne/32/19_2.png) [@simonbyrne](https://discourse.julialang.org/u/simonbyrne)\
**Post date:** [March 5, 2018, 12:26am UTC](https://discourse.julialang.org/t/really-not-irrational/9485/16 "2018-03-05T00:26:37Z")

</div>

See also last years pi day blog post for an explanation of `Irrational` [Some fun with Π in Julia](https://julialang.org/blog/2017/03/piday)

---

<div class="post-metadata">

**Author:** ![jeff.bezanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff.bezanson/32/48_2.png) [@jeff.bezanson](https://discourse.julialang.org/u/jeff.bezanson)\
**Post date:** [March 9, 2018, 7:44pm UTC](https://discourse.julialang.org/t/really-not-irrational/9485/17 "2018-03-09T19:44:47Z")

</div>

Very cool. This is a good opportunity to teach about differences between theory and its instantiations on real computers. `sqrt(2) isa Irrational` being false tells you something about what `sqrt(2)` actually does — it’s returning a rational approximation to the true value, since we decided that would be more useful. So that answer is “correct” in the highly literal way that computers work.

Another fun example is `Float64(pi) < pi`, which is true.

It would be a great exercise to implement an irrational type representing square roots, if you think she might be interested in that.

---

<div class="post-metadata">

**Author:** ![jgoldfar](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jgoldfar/32/2664_2.png) [@jgoldfar](https://discourse.julialang.org/u/jgoldfar)\
**Post date:** [March 10, 2018, 5:23pm UTC](https://discourse.julialang.org/t/really-not-irrational/9485/18 "2018-03-10T17:23:53Z")

</div>

FYI: [https://github.com/wbhart/Nemo.jl](https://github.com/wbhart/Nemo.jl)

---

<div class="post-metadata">

**Author:** ![chakravala](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chakravala/32/6832_2.png) [@chakravala](https://discourse.julialang.org/u/chakravala)\
**Post date:** [March 22, 2018, 11:35am UTC](https://discourse.julialang.org/t/really-not-irrational/9485/19 "2018-03-22T11:35:14Z")

</div>

> [@Ralph\_Smith](#):
>
> julia\> typeof(log(ℯ^2))  
> Float64

Not sure if people know about this, but with my package you can do stuff like this:

```Julia
julia> using Reduce
Reduce (Free PSL version, revision 4521), 11-Mar-2018 ...

julia> log(:(e^2))
2

julia> typeof(ans)
Int64

```

But I just realized that this doesn’t work on symbols yet (it works for `Expr` objects), so `log(:e)` doesn’t work yet, but that should be a simple fix to implement.

---

<div class="post-metadata">

**Author:** ![chakravala](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chakravala/32/6832_2.png) [@chakravala](https://discourse.julialang.org/u/chakravala)\
**Post date:** [March 22, 2018, 12:55pm UTC](https://discourse.julialang.org/t/really-not-irrational/9485/20 "2018-03-22T12:55:24Z")

</div>

Alright, so I fixed it, now you can do the symbol type `using Reduce`:

```Julia
julia> log(:e)
1

```

But to have the code generation for macros for all these functions like `@log e^2` my question needs ans:

> [@Interpolate inside a Quote inside a Macro inside a Quote?](https://discourse.julialang.org/t/interpolate-inside-a-quote-inside-a-macro-inside-a-quote/9888/1):
>
> Is it possible to do this? I need this for my package [Reduce.jl](https://github.com/chakravala/Reduce.jl) Let’s say I have a bunch of functions, call them fun and I need a macro for each macro fun(expr) :(fun($expr)) end But I need to automate this using code generation. So I want to do something like for fun in [:name\_of\_func, :name\_of\_another\_func] quote macro $fun(expr) ## what to put here ? end end end Now, so the line of code needs to look like this, but it needs to appear inside the quo…
