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

The result of an empty intersection of ranges is confusing #40331

Closed
gbaraldi opened this issue Apr 3, 2021 · 10 comments
Closed

The result of an empty intersection of ranges is confusing #40331

gbaraldi opened this issue Apr 3, 2021 · 10 comments
Labels
display and printing Aesthetics and correctness of printed representations of objects. good first issue Indicates a good issue for first-time contributors to Julia ranges Everything AbstractRange

Comments

@gbaraldi
Copy link
Member

gbaraldi commented Apr 3, 2021

If you call intersectbetween two ranges and the result is empty it returns an empty range of the form 5:4 as in like

julia> a = 1:3
1:3

julia> b = 5:6
5:6

julia> intersect(a,b)
5:4

That can be confusing since you might interpret 5:4 as 5:-1:4
Using Float ranges gives a different result though

julia> a = 30:0.5:42
30.0:0.5:42.0

julia> b = 15:0.5:25
15.0:0.5:25.0

julia> intersect(a,b)
Float64[]
@gbaraldi gbaraldi changed the title The result of and empty intersection of ranges is confusing The result of an empty intersection of ranges is confusing Apr 3, 2021
@sostock
Copy link
Contributor

sostock commented Apr 5, 2021

Maybe we could print empty ranges differently, adding a hint like the following:

julia> 5:4
5:4 (empty UnitRange{Int})

@gbaraldi
Copy link
Member Author

gbaraldi commented Apr 5, 2021

There should be a better way to show an empty range then 5:4 or 6.0:5.0 since one, it's not unique and two it's confusing. And using array notation might be even worse.

@vtjnash
Copy link
Member

vtjnash commented Apr 5, 2021

Commonly, we summarize by printing the length of an array. Might we useful always?

julia> codeunits("a")
1-element Base.CodeUnits{UInt8, String}:
 0x61

julia> codeunits("")
0-element Base.CodeUnits{UInt8, String}

julia> ans isa AbstractVector
true

@vtjnash vtjnash added the display and printing Aesthetics and correctness of printed representations of objects. label Nov 19, 2021
@lazarusA
Copy link

lazarusA commented Dec 4, 2022

this issue should definitely be addressed somehow. For all things (sets) empty probably the best should be to print

julia > intersect(a,b)
 ∅

or similar to [by @sostock ]

julia > intersect(a,b)
empty UnitRange{Int}

without any ranges left in the printing, which are really confusing.

@sostock
Copy link
Contributor

sostock commented Dec 4, 2022

For ranges, the start/stop values sometimes carry meaning even for empty ranges. From the searchsorted docstring:

julia> searchsorted([1, 2, 4, 5, 5, 7], 3) # no match, insert in the middle
3:2

julia> searchsorted([1, 2, 4, 5, 5, 7], 9) # no match, insert at end
7:6

Here, not printing the values for empty ranges would hide where the number would be inserted. Therefore, I think that the start/stop values should always be printed for ranges, even when they are empty.

@lazarusA
Copy link

lazarusA commented Dec 4, 2022

hide where the number would be inserted.

the problem is that the output looks like the actual value output, when in practice one needs the emptyness of that operation. If you want to keep that information for whatever reason, then it should appear after the actual value output, e.g.,

julia> searchsorted([1, 2, 4, 5, 5, 7], 3)
∅ (empty 3:2)

@mcabbott
Copy link
Contributor

mcabbott commented Dec 5, 2022

To try out always printing the length, as other arrays do:

julia> function Base.show(io::IO, ::MIME"text/plain", r::AbstractRange)
         summary(io, r); print(io, ":\n "); show(io, r)
       end

julia> intersect(1:3, 5:6)
0-element UnitRange{Int64}:
 5:4

julia> 1:2:3
2-element StepRange{Int64, Int64}:
 1:2:3

julia> LinRange(1,2,3)  # unchanged
3-element LinRange{Float64, Int64}:
 1.0, 1.5, 2.0

julia> range(1,2,3)  # quite long
3-element StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}:
 1.0:0.5:2.0

@LilithHafner LilithHafner added the triage This should be discussed on a triage call label Nov 6, 2024
@oscardssmith
Copy link
Member

Triage thinks the first answer proposed was the right one.

5:4 (empty UnitRange{Int})

@oscardssmith oscardssmith added good first issue Indicates a good issue for first-time contributors to Julia and removed triage This should be discussed on a triage call labels Nov 7, 2024
@StefanKarpinski
Copy link
Member

Maybe just 5:4 (empty range) since most don't care about the type?

@nsajko nsajko added the ranges Everything AbstractRange label Mar 11, 2025
LilithHafner pushed a commit that referenced this issue Mar 19, 2025
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
```sh
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)
```
@prashantrahul141
Copy link
Contributor

I think we can close this now?

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. good first issue Indicates a good issue for first-time contributors to Julia ranges Everything AbstractRange
Projects
None yet
Development

No branches or pull requests

10 participants