diff --git a/base/range.jl b/base/range.jl index 5f30a31a0bde5..1d67bafa9fb0e 100644 --- a/base/range.jl +++ b/base/range.jl @@ -47,33 +47,38 @@ function _colon(start::T, step, stop::T) where T end """ - range(start[, stop]; length, stop, step=1) + range(start; stop, length) # any one keyword, step = 1 + range(start, stop; length, step) # any one keyword + range(start; stop, length, step) # any two keywords -Given a starting value, construct a range either by length or from `start` to `stop`, -optionally with a given step (defaults to 1, a [`UnitRange`](@ref)). -One of `length` or `stop` is required. If `length`, `stop`, and `step` are all specified, they must agree. +Construct at an `AbstractRange`, given a starting value and one or two required keyword arguments. -If `length` and `stop` are provided and `step` is not, the step size will be computed -automatically such that there are `length` linearly spaced elements in the range. - -If `step` and `stop` are provided and `length` is not, the overall range length will be computed -automatically such that the elements are `step` spaced. +`start` is the first value of range. `stop` is the upper bound of the range. `length` is the number of +elements of range. `step` is the difference between each element of the range. -Special care is taken to ensure intermediate values are computed rationally. -To avoid this induced overhead, see the [`LinRange`](@ref) constructor. +If the only keyword is `stop` or `length` and all arguments are integers this results in a `UnitRange`. +Otherwise it constructs an `AbstractRange` for which any two of `stop, length, step` +can be specified. Giving all three will result in an error. +`stop` may be a keyword, or the 2nd positional argument along with another keyword argument. -`stop` may be specified as either a positional or keyword argument. +See the Extended help for more details. !!! compat "Julia 1.1" `stop` as a positional argument requires at least Julia 1.1. # Examples ```jldoctest -julia> range(1, length=100) -1:100 +julia> range(2, length=100) +2:101 -julia> range(1, stop=100) -1:100 +julia> range(3, stop=100) +3:100 + +julia> range(4, stop=100, step=2) +4:2:100 + +julia> range(1, stop=3.3) +1.0:1.0:3.0 julia> range(1, step=5, length=100) 1:5:496 @@ -86,7 +91,85 @@ julia> range(1, 10, length=101) julia> range(1, 100, step=5) 1:5:96 + +julia> julia> range(1,5) +ERROR: ArgumentError: At least one of `length` or `step` must be specified +[...] + +julia> range(1; stop=5, length=5, step=1) +ERROR: ArgumentError: Too many arguments specified; try passing only one of `stop` or `length` +[...] ``` + +# Extended help + range(start; length) + range(start; stop) + + range(start; stop, length) + range(start, stop; length) + + range(start; stop, step) + range(start, stop; step) + + range(start; length, step) + +The above forms of `range` are the only acceptable forms of the range call. + +## Arguments + +The relationship of the arguments is described by the following equation +written as an expression that must evaluate to true. + + `start + step * (length-1) <= stop` + +### `length` argument specified + +If `length` is given as the sole keyword argument, `step` is assumed to be 1.0. + +### `stop` argument specified + +`stop` serves only as an upper bound and may be included as the last element. +If `stop` is given as the sole keyword argument, `step` is assumed to be 1.0. +If `stop` is given as a positional argument, a keyword argument of either +`length` or `step` must be specified per below. + +### `stop` and `length` specified + +If `length` and `stop` are provided and `step` is not, the step size will be computed +automatically such that there are `length` linearly spaced elements in the range inclusive +of `stop`. + +### `stop` and `step` specified + +If `step` and `stop` are provided and `length` is not, the overall range length will be computed +automatically such that the elements are `step` spaced. The last element of the range +may not be `stop` in this case. + +### `length` and `stop` specified + +If `length` and `step are provided and `stop` is not, then the resulting range will include +`length` elements that are `step` spaced. The last element will be +`stop = start + step * (length-1)`. + +### `length`, `stop`, and `step` cannot be all specified + +An [`ArgumentError`](@ref) will be thrown if all three keyword arguments are specified. + +## `UnitRange` construction + +To specify a [`UnitRange`](@ref) where `step` is 1, use one of the following +where `start`, `length`, and `stop` are all integers. +* range(start, length=length) +* range(start, stop=stop) +* `start:stop` +* `(:)(start,stop)` + +Specifying a `step` of 1 explicitly, does not result in a [`UnitRange`](@ref). + +## Rationally computed intermediate values + +Special care is taken to ensure intermediate values are computed rationally. +To avoid this induced overhead, see the [`LinRange`](@ref) constructor. """ range(start; length::Union{Integer,Nothing}=nothing, stop=nothing, step=nothing) = _range(start, step, stop, length)