-
Notifications
You must be signed in to change notification settings - Fork 46
Embrace pairs for show and construction
#179
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
Conversation
This changes the `show` method for `IdOffsetRange` to print as follows: ``` julia> using OffsetArrays: IdOffsetRange julia> IdOffsetRange(3:5, 1) (2 => 4):(4 => 6) ``` It allows you to construct them as displayed. The advantage is that this makes both the indexes and the values apparent. It fixes the problem that two ranges with different indexes print the same: ```julia julia> r1 = IdOffsetRange(0:2, 0) OffsetArrays.IdOffsetRange(0:2) julia> firstindex(r1) 1 julia> r2 = IdOffsetRange(Base.IdentityUnitRange(-1:1), 1) OffsetArrays.IdOffsetRange(0:2) julia> firstindex(r2) 0 ```
Codecov Report
@@ Coverage Diff @@
## master #179 +/- ##
=======================================
Coverage 98.85% 98.85%
=======================================
Files 4 4
Lines 261 261
=======================================
Hits 258 258
Misses 3 3 Continue to review full report at Codecov.
|
|
Following the pattern in Julia itself, printing changes may not be considered breaking. OTOH, if we want to take advantage of the opportunity to fix Lines 56 to 74 in 42c8cf6
then we could go to v2. (We'd want to decide #174 at the same time.) |
|
The constructor commits type-piracy though, although the method |
|
Agreed, but personally I think it's worth it. "Fixing" a MethodError is a pretty weak form of piracy. But perhaps we should move IdOffsetRange to Base, and have a stub here for previous Julia versions? |
|
It's not very clear to me how I'm sitting tight to see how JuliaLang/julia#39069 is progressing |
|
Interesting point. Any other ideas? From my standpoint, the current printing isn't really acceptable in the long run since it doesn't show the indices. So we have to do something. It would be ideal if it's |
|
How about |
|
But that doesn't distinguish the indices from the values. The advantage here is that it's a range-of-pairs, |
|
The type only contains a range and an offset, so it seems a little confusing to me to enter it with a redundant 4th number, which if you get wrong gives an error (presumably). It could still be printed in some more informative way, maybe when |
|
Understood, but for reference, do you think it's weird to have a 4th value for the |
|
The dictionary is A more boring option would just be to make this work, and print it: |
| istop - istart == rstop - rstart || throw_argerr(istart, istop, rstart, rstop) | ||
| offset = istart - 1 | ||
| return IdOffsetRange(rstart-offset : rstop-offset, offset) | ||
| end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we're interpreting => as key => value pair, then I think 2:4 => 5:7 should be equivalent to (2 => 5):(4 => 7) instead of (2 => 4):(5 => 7)
Hence if we introduce this in Base, it should be something like
Base.:(:)(src::Pair, dest::Pair) = src.first:dest.first => src.second:dest.secondForcing it to return an IdOffsetRange makes little sense to me as it breaks the 2:4 => 5:7 and (2 => 5):(4 => 7) equivalence by adding a new range meaning (IdOffsetRange) to it. I mean, it's as little sense as making (1, 1):(4, 4) to be CartesianIndex(2, 2):CartesianIndex(4, 4).
It might be better to adjust this PR to:
julia> IdOffsetRange(4:6, 1)
IdOffsetRange((2 => 5):(4 => 7))There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR doesn't "do anything" with 2:4 => 5:7. A Pair-of-ranges seems like a well-defined concept. Conversely, a range-of-pairs currently is an error:
julia> 2:4 => 5:7 # no error
2:4 => 5:7
julia> (2=>5) : (4=>7)
ERROR: MethodError: no method matching -(::Pair{Int64, Int64}, ::Pair{Int64, Int64})
Stacktrace:
[1] (::Colon)(start::Pair{Int64, Int64}, stop::Pair{Int64, Int64})
@ Base ./range.jl:7
[2] top-level scope
@ REPL[1]:1Consequently we have the opportunity to make it mean something. We could even rename IdOffsetRange to RangePair. They're "Id" (idempotent) only when the parent range starts at 1:
julia> r = OffsetArrays.IdOffsetRange(1:5, -3)
(-2 => -2):(2 => 2)
julia> axes(r)
((-2 => -2):(2 => 2),)
julia> r = OffsetArrays.IdOffsetRange(2:6, -3)
(-2 => -1):(2 => 3)
julia> axes(r)
((-2 => -2):(2 => 2),)|
Since most of the complaints seem to be about the construction part, how about I rip that out and we just have the display? JuliaLang/julia#39069 has been closed, so I don't think there's any concern about conflict. |
|
I'm in favor of this as it is undoubtedly helpful, albeit a bit tricky to parse |
|
We could also do and add that as a keyword-only constructor. LIke the Pairs implementation, it doesn't show any of the types but I think that's much less important (and arguably something we should de-emphasize as an internal matter). |
This changes the
showmethod forIdOffsetRangeto print as follows:It allows you to construct them as displayed:
The advantage is that this makes both the indexes and the values apparent.
It fixes the problem that two ranges with different indexes currently print the same: