Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

display "(empty range)" in case of empty ranges #57697

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

prashantrahul141
Copy link

As mentioned in #40331, empty ranges could be confusing. This pr adds a message "(empty range)" incase if the range is empty.
So for the example given in the issue

julia> a = 1:3
1:3

julia> b = 5:6
5:6

julia> intersect(a,b)  # old behaviour
5:4

julia> intersect(a,b)  # new behaviour
5:4 (empty range)

@@ -618,6 +618,9 @@ function show(io::IO, r::LinRange{T}) where {T}
print(io, ", ")
show(io, length(r))
print(io, ')')
if isempty(r)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the 2-argument show, which should be parseable Julia code. See https://docs.julialang.org/en/v1/base/io-network/#Base.show-Tuple{IO,%20Any} .

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it be better to use compact in IOContext to control this like @mikmoore suggested here?

basically this

    if !get(io, :compact, false) && isempty(r)
        print(io, " (empty range)")
    end

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should be in a three arg show method.

Copy link
Contributor

@Seelengrab Seelengrab Mar 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's what I was getting at. From the docstring I linked:

For a more verbose human-readable text output for objects of type T, define show(io::IO, ::MIME"text/plain", ::T) in addition.

:compact showing is unrelated to this.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see now. So I assume it would be better to define show(io::IO, ::MIME"text/plain", ::T) for range types rather than change the existing ones?

@mikmoore
Copy link
Contributor

Can we tweak this so that it doesn't print when IOContext is compact?

And also try to minimize its interference with the ability to copy-paste to reconstruct an object (which might be addressed by the compact)? For example,

julia> print([1:2, 3:2, 4:5])
UnitRange{Int64}[1:2, 3:2, 4:5]

I can use UnitRange{Int64}[1:2, 3:2, 4:5] to reconstruct this object but UnitRange{Int64}[1:2, 3:2 (empty range), 4:5] is a ParseError.

@jishnub
Copy link
Member

jishnub commented Mar 10, 2025

If I understand correctly, the issue is mainly with an empty UnitRange being confused with a StepRange with a step of -1? Do we need this for every range type?

@prashantrahul141
Copy link
Author

I assume a better approach would be to define a 3-argument show (show(io::IO, ::MIME"text/plain", ::T)) for range types. As @jishnub mentioned, should it be defined for all range types or just for UnitRange?

I think it should be defined for all range types since 3-argument show is meant to display additional details and to ensure consistency.

@jishnub
Copy link
Member

jishnub commented Mar 11, 2025

To take the LinRange example, here are the displayed forms for the 3 and 2-argument show methods:

julia> show(stdout, MIME"text/plain"(), LinRange(2.0, 4.5, 5))
5-element LinRange{Float64, Int64}:
 2.0, 2.625, 3.25, 3.875, 4.5

julia> show(stdout, LinRange(2.0, 4.5, 5))
LinRange{Float64}(2.0, 4.5, 5)

In the first case, the length is explicitly mentioned in the summary. In the second case, the last parameter corresponds to the length, although this isn't explicitly pointed out (as this needs to be runnable julia code). Since we're discussing the 3-argument case here, the displayed form seems to indicate the length adequately?

I feel the issue is mainly with ranges where the 3-argument show uses the 2-argument method for the actual display. Or, in other words, any range that does not specialize the 3-argument show method. LinRange and LogRange are ones where the 3-argument form does display the summary, so these may be excluded.

@prashantrahul141
Copy link
Author

So I am trying to define a 3 argument show in base/range.jl, something like:

function Base.show(io::IO, ::MIME"text/plain", r::AbstractUnitRange{T}) where T
   # impl
end

and I am getting this

error during bootstrap:
LoadError(at "Base_compiler.jl" line 3: LoadError(at "range.jl" line 1119: LoadError(at "range.jl" line 1119: UndefVarError(var=:var"@MIME_str", world=0x0000000000000e4e, scope=Base))))
ijl_undefined_var_error at /home/prashant/Projects/julia-fork/src/rtutils.c:154
jl_eval_global_var at /home/prashant/Projects/julia-fork/src/interpreter.c:169 [inlined]
eval_value at /home/prashant/Projects/julia-fork/src/interpreter.c:223
jl_interpret_toplevel_expr_in at /home/prashant/Projects/julia-fork/src/interpreter.c:919
No code info - unknown interpreter state!

I am assuming this is because maybe MIME is not available at this stage of bootstraping. How can I get around this?

@nsajko nsajko added display and printing Aesthetics and correctness of printed representations of objects. ranges Everything AbstractRange labels Mar 11, 2025
@nsajko
Copy link
Contributor

nsajko commented Mar 11, 2025

not available at this stage of bootstraping. How can I get around this?

MIME and friends are included into Base here:

julia/base/Base.jl

Lines 63 to 64 in 885b1cd

include("multimedia.jl")
using .Multimedia

... so try inserting your method somewhere after that point, maybe try one of these files:

julia/base/Base.jl

Lines 112 to 113 in 885b1cd

include("show.jl")
include("arrayshow.jl")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
display and printing Aesthetics and correctness of printed representations of objects. ranges Everything AbstractRange
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants