Skip to content

Commit bd6cd3c

Browse files
committed
range(; stop) and range(; length)
1 parent 26a721b commit bd6cd3c

File tree

3 files changed

+53
-6
lines changed

3 files changed

+53
-6
lines changed

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ Standard library changes
4141

4242
* `count` and `findall` now accept an `AbstractChar` argument to search for a character in a string ([#38675]).
4343
* `range` now supports `start` as an optional keyword argument ([#38041]).
44+
* `range` accepts either `stop` or `length` as a sole keyword argument ([#39241])
4445
* `islowercase` and `isuppercase` are now compliant with the Unicode lower/uppercase categories ([#38574]).
4546
* `iseven` and `isodd` functions now support non-`Integer` numeric types ([#38976]).
4647
* `escape_string` can now receive a collection of characters in the keyword

base/range.jl

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,10 @@ Construct a specialized array with evenly spaced elements and optimized storage
5555
Mathematically a range is uniquely determined by any three of `start`, `step`, `stop` and `length`.
5656
Valid invocations of range are:
5757
* Call `range` with any three of `start`, `step`, `stop`, `length`.
58-
* Call `range` with two of `start`, `stop`, `length`. In this case `step` will be assumed
59-
to be one. If both arguments are Integers, a [`UnitRange`](@ref) will be returned.
58+
* Call `range` with two of `start`, `stop`, `length`. In this case `step` will be assumed to be one.
59+
* Call `range` with one of `stop` or `length`. `start` and `step` will be assumed to be one.
60+
61+
See Extended Help for additional details on the returned type.
6062
6163
# Examples
6264
```jldoctest
@@ -86,6 +88,15 @@ julia> range(stop=10, step=1, length=5)
8688
8789
julia> range(start=1, step=1, stop=10)
8890
1:1:10
91+
92+
julia> range(; length = 10)
93+
Base.OneTo(10)
94+
95+
julia> range(; stop = 6)
96+
Base.OneTo(6)
97+
98+
julia> range(; stop = 6.5)
99+
1.0:1.0:6.0
89100
```
90101
If `length` is not specified and `stop - start` is not an integer multiple of `step`, a range that ends before `stop` will be produced.
91102
```jldoctest
@@ -103,7 +114,20 @@ If both are specified as positional arguments, one of `step` or `length` must al
103114
`stop` as a positional argument requires at least Julia 1.1.
104115
105116
!!! compat "Julia 1.7"
106-
`start` as a keyword argument requires at least Julia 1.7.
117+
`start` as a keyword argument, or
118+
`stop` or `length` as a sole argument requires at least Julia 1.7.
119+
120+
# Extended Help
121+
122+
`range` will produce a `Base.OneTo` when the arguments are Integers and
123+
* Only `length` is provided
124+
* Only `stop` is provided
125+
126+
`range` will produce a `UnitRange` when the arguments are Integers and
127+
* Only `start` and `stop` are provided
128+
* Only `length` and `stop` are provided
129+
130+
A `UnitRange` is not produced if `step` is provided even if specified as one.
107131
"""
108132
function range end
109133

@@ -129,8 +153,8 @@ range(;start=nothing, stop=nothing, length::Union{Integer, Nothing}=nothing, ste
129153
_range(start, step, stop, length)
130154

131155
_range(start::Nothing, step::Nothing, stop::Nothing, len::Nothing) = range_error(start, step, stop, len)
132-
_range(start::Nothing, step::Nothing, stop::Nothing, len::Any ) = range_error(start, step, stop, len)
133-
_range(start::Nothing, step::Nothing, stop::Any , len::Nothing) = range_error(start, step, stop, len)
156+
_range(start::Nothing, step::Nothing, stop::Nothing, len::Any ) = range_length(len)
157+
_range(start::Nothing, step::Nothing, stop::Any , len::Nothing) = range_stop(stop)
134158
_range(start::Nothing, step::Nothing, stop::Any , len::Any ) = range_stop_length(stop, len)
135159
_range(start::Nothing, step::Any , stop::Nothing, len::Nothing) = range_error(start, step, stop, len)
136160
_range(start::Nothing, step::Any , stop::Nothing, len::Any ) = range_error(start, step, stop, len)
@@ -145,6 +169,11 @@ _range(start::Any , step::Any , stop::Nothing, len::Any ) = range_start
145169
_range(start::Any , step::Any , stop::Any , len::Nothing) = range_start_step_stop(start, step, stop)
146170
_range(start::Any , step::Any , stop::Any , len::Any ) = range_error(start, step, stop, len)
147171

172+
range_length(len::Integer) = OneTo(len)
173+
174+
range_stop(stop) = oneunit(stop):stop
175+
range_stop(stop::Integer) = OneTo(stop)
176+
148177
range_stop_length(stop, length) = (stop-length+1):stop
149178

150179
range_step_stop_length(step, stop, length) = reverse(range_start_step_length(stop, -step, length))

test/ranges.jl

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,19 @@
1717
# the next one uses ==, because it changes the eltype
1818
@test r == range(start=first(r), stop=last(r), length=length(r))
1919
@test r === range( stop=last(r), length=length(r))
20+
21+
r = 1:5
22+
o = Base.OneTo(5)
23+
let start=first(r), step=step(r), stop=last(r), length=length(r)
24+
@test o === range(; stop )
25+
@test o === range(; length)
26+
@test r === range(; start, stop )
27+
@test r === range(; stop, length)
28+
# the next three lines uses ==, because it changes the eltype
29+
@test r == range(; start, stop, length)
30+
@test r == range(; start, step, length)
31+
@test r == range(; stop=Float64(stop))
32+
end
2033
end
2134
end
2235

@@ -1446,8 +1459,12 @@ end
14461459
@test_throws ArgumentError range(1)
14471460
@test_throws ArgumentError range(nothing)
14481461
@test_throws ArgumentError range(1, step=4)
1449-
@test_throws ArgumentError range(nothing, length=2)
1462+
@test_throws ArgumentError range(; step=1, length=6)
1463+
@test_throws ArgumentError range(; step=2, stop=7.5)
14501464
@test_throws ArgumentError range(1.0, step=0.25, stop=2.0, length=5)
1465+
@test_throws ArgumentError range(; stop=nothing)
1466+
@test_throws ArgumentError range(; length=nothing)
1467+
@test_throws TypeError range(; length=5.5)
14511468
end
14521469

14531470
@testset "issue #23300#issuecomment-371575548" begin

0 commit comments

Comments
 (0)