Using print on pi produces π rather than 3.141592653589793

Is it normal that Julia’s print prints constants as their character or name rather than an interpretation of the numerical value?

For instance

julia> print(pi)
π

Multiply it by something though, e.g. 1, forces the interpretation as a number:

julia> print(1.0*pi)
3.141592653589793

But… not all things change it:

julia> print(abs(pi))
π

Here is another:

julia> print(Base.MathConstants.catalan)
catalan

Rather than:

julia> print(1.0*Base.MathConstants.catalan)
0.915965594177219

Similarly:

julia> print(nothing)
nothing

Which I would expect would print… nothing rather than the word “nothing”.
The string function, and perhaps others, seems to behave similarly e.g.:

julia> string(pi)
"π"

And obviously using spintf or similar functions, we can avoid these issues.

julia> using Printf
julia> @sprintf("%.15f",pi)
"3.141592653589793"

This is an issue for me when I want to print things in a function which has optional inputs, the optional input is nothing when not provided,… leading to Julia now printing the word “nothing”. The context is this GitHub issue for those who want to learn more about that I am trying to do. I have a workaround, it just seems annoying that a thing I tend to use as a number, e.g. pi doesn’t get converted to a number here.

Thanks!

1 Like

The constant pi is indeed a number, but it has the type irrational if I am not mistaken. And an irrational number can not be losslessly converted to a string as required for print. Except for, or course, convertion to the name of the constant, which is the behaviour you are seeing. The reason multiplication does what you want is that it promotes the irrational factor to a floating point product.

So you want to promote two different types: nothing, and number (which is an abstract type). Would it make sense to convert any input to a common type before printing?

6 Likes

Notice that π is of type Irrational.

julia> π
π = 3.1415926535897...

julia> typeof(π)
Irrational{:π}

If you want a specific representation, you can ask for it.

julia> Float16(π)
Float16(3.14)

julia> Float32(π)
3.1415927f0

julia> Float64(π)
3.141592653589793

julia> rationalize(Float64(π))
165707065//52746197

I need to think about nothing for a little bit longer.

6 Likes

XML.jl does a form of serialization by expanding their XML type to an XML string representing the document, and probably should specialize that serialization of nothing to the empty string and Irrational to a numeric representation of the number, instead of relying on print directly.

As for why print has that behavior - it’s for human readable output/canonical representation of a value, not a machine readable specific format.

1 Like

Printing nothing has indeed taken a good amount of thought: see Interpolation of nothing should be an error (#27352) and Allow nothing to be printed (#32148) for two breadcrumbs if you’re interested.

2 Likes

Thanks, this will be my new motto!

8 Likes

What gives me pause at the moment is that this behavior is not consistent with the REPL display. That is the REPL seems ro have a special case for nothing and does not display it.

julia> nothing

julia> display(nothing)
nothing

julia> show(nothing)
nothing
3 Likes