# Irrational numbers are unique, so which package gets to define them?

Irrational numbers are singleton types and are unique, so we have something like

``````julia> Irrational{:pi}() === Irrational{:pi}()
true
``````

Not many irrational numbers are defined in `Base`, therefore packages are free to define their own numbers. However the macro `Base.@irrational` that may be used to define a new irrational number `a` simultaneously defines `Base.Float64(a)`. This therefore means that a second package that also defines the same number `a` overwrites the original method definition of `Float64(a)` with the new – albeit identical – type. For example:

``````julia> module A
Base.@irrational a 1.0 float(big(1))
end
Main.A

julia> module B
Base.@irrational a 1.0 float(big(1))
end
Main.B

julia> @which Float64(A.a)
Float64(::Irrational{:a}) in Main.B at irrationals.jl:189
``````

Now this isn’t really a problem for the most part (aside from the unexpected type piracy), since

``````julia> A.a === B.a
true
``````

and the results would be identical. However when functions are overwritten like this, package precompilation gets broken. One solution appears to be to import `A.a` inside `B`, but this means that `B` needs to depend on `A` that might otherwise be unrelated. Another solution is to rename the number in `B` and call it something other than `a`. However this is undesirable, eg. you wouldn’t name `ℯ` as something else. So which package gets to define the number without precompilation hurdles?

For example, StatsFuns.jl defines quite a few irrationals. How to avoid conflicts with `StatsFuns` if eg. we want to define `sqrt2`?

While `Base` uses a symbol for the type parameter, this is merely a convention. You can define your own type (possibly parametrizing it by a symbol, too) and use that as a parameter. Eg

``````struct MyIrrational{T} end

Base.Float64(::Irrational{MyIrrational{:sqrt2}}) = √2
``````

From that point on, just avoid type piracy and you will be fine.

4 Likes
{"ft_lang_label":"__label__en","ft_lang_prob":0.85684025,"math_prob":0.921145,"size":1497,"snap":"2022-05-2022-21","text_gpt3_token_len":378,"char_repetition_ratio":0.1399866,"word_repetition_ratio":0.008695652,"special_character_ratio":0.2271209,"punctuation_ratio":0.13953489,"nsfw_num_words":0,"has_unicode_error":false,"math_prob_llama3":0.9712359,"pos_list":[0],"im_url_duplicate_count":[null],"WARC_HEADER":"{\"WARC-Type\":\"response\",\"WARC-Date\":\"2022-05-21T12:20:14Z\",\"WARC-Record-ID\":\"<urn:uuid:4177451f-d613-4283-ba8d-441d63514156>\",\"Content-Length\":\"23897\",\"Content-Type\":\"application/http; msgtype=response\",\"WARC-Warcinfo-ID\":\"<urn:uuid:44b1c6c5-833a-4d82-84da-b8ff5962f661>\",\"WARC-Concurrent-To\":\"<urn:uuid:501da7e9-1112-442f-88f4-6360f0f69871>\",\"WARC-IP-Address\":\"64.71.144.205\",\"WARC-Target-URI\":\"https://discourse.julialang.org/t/irrational-numbers-are-unique-so-which-package-gets-to-define-them/44798\",\"WARC-Payload-Digest\":\"sha1:CSXLUUKBT7EOUH7YT3NAVWVIZ5JPSJPM\",\"WARC-Block-Digest\":\"sha1:U6Z7VRTDZ3YY37D5HBWIDDXGSXWZUSGO\",\"WARC-Identified-Payload-Type\":\"text/html\",\"warc_filename\":\"/cc_download/warc_2022/CC-MAIN-2022-21/CC-MAIN-2022-21_segments_1652662539101.40_warc_CC-MAIN-20220521112022-20220521142022-00631.warc.gz\"}"}