From 01d89c66d17c9e6256609f7904979442ed96da7b Mon Sep 17 00:00:00 2001 From: Mark Kittisopikul Date: Sat, 3 Oct 2020 18:17:11 -0400 Subject: [PATCH 01/10] Doc PR to clarify range usage The current documentation for `range` is at worse wrong and at best misleading. This documentation change clarifies the usage of `range`. --- base/range.jl | 50 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/base/range.jl b/base/range.jl index 5f30a31a0bde5..edbb4e363da73 100644 --- a/base/range.jl +++ b/base/range.jl @@ -47,11 +47,31 @@ function _colon(start::T, step, stop::T) where T end """ - range(start[, stop]; length, stop, step=1) - -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. + range(start; stop) + range(start; length) + range(start, stop; length) + range(start, stop; step) + + # The following cause an ArgumentError to be thrown. + range(start, stop) # Must specify either length or step + range(start; step) # Cannot specify step alone + range(start, stop; length, step) # Cannot specify all of stop, length, and step + range(start; stop, length, step) # Cannot specify all of stop, length, and step + +Given a starting value, construct an iterable with the first element of `start`. +One keyword argument of either `length`, `stop`, or `step` is required to avoid +ambiguity. + +To specify a [`UnitRange`](@ref) where `step` is 1, use either +* range(start, length=length) +* `start:stop` +* `(:)(start,stop)` + +`stop` may be included as the last element of the iterable depending on `step`. +`stop` may be specified as either a positional or keyword argument. +If `stop` is given as a positional argument, a keyword argument. +of either `length` or `step` must be specified. +If `stop` is given as the sole keyword argument, a `step` is assumed be 1.0. 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. @@ -59,11 +79,11 @@ 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. +`length`, `stop`, and `step` cannot be all specified. + Special care is taken to ensure intermediate values are computed rationally. To avoid this induced overhead, see the [`LinRange`](@ref) constructor. -`stop` may be specified as either a positional or keyword argument. - !!! compat "Julia 1.1" `stop` as a positional argument requires at least Julia 1.1. @@ -75,6 +95,9 @@ julia> range(1, length=100) julia> range(1, stop=100) 1:100 +julia> range(1, stop=3.3) +1.0:1.0:3.0 + julia> range(1, step=5, length=100) 1:5:496 @@ -86,6 +109,19 @@ julia> range(1, 10, length=101) julia> range(1, 100, step=5) 1:5:96 + +julia> try range(1, 5) catch e println(e) end +ArgumentError("At least one of `length` or `step` must be specified") + +julia> try range(1, step=1) catch e println(e) end +ArgumentError("At least one of `length` or `stop` must be specified") + +julia> try range(1, 5; length=5, step=1) catch e println(e) end +ArgumentError("Too many arguments specified; try passing only one of `stop` or `length`") + +julia> try range(1; stop=5, length=5, step=1) catch e println(e) end +ArgumentError("Too many arguments specified; try passing only one of `stop` or `length`") + ``` """ range(start; length::Union{Integer,Nothing}=nothing, stop=nothing, step=nothing) = From ecf1ed163d5b0cd0b66ea2de6ba096f49150cb6f Mon Sep 17 00:00:00 2001 From: Mark Kittisopikul Date: Mon, 5 Oct 2020 00:23:42 -0400 Subject: [PATCH 02/10] Edited documentation, specified ints UnitRange * `start`, `length`, and `stop` must be integers to get a `UnitRange` * A `step` of 1 does not result in a `UnitRange` --- base/range.jl | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/base/range.jl b/base/range.jl index edbb4e363da73..cd077333f4298 100644 --- a/base/range.jl +++ b/base/range.jl @@ -62,14 +62,18 @@ Given a starting value, construct an iterable with the first element of `start`. One keyword argument of either `length`, `stop`, or `step` is required to avoid ambiguity. -To specify a [`UnitRange`](@ref) where `step` is 1, use either +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). + `stop` may be included as the last element of the iterable depending on `step`. `stop` may be specified as either a positional or keyword argument. -If `stop` is given as a positional argument, a keyword argument. +If `stop` is given as a positional argument, a keyword argument of either `length` or `step` must be specified. If `stop` is given as the sole keyword argument, a `step` is assumed be 1.0. @@ -77,9 +81,10 @@ If `length` and `stop` are provided and `step` is not, the step size will be com 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. +automatically such that the elements are `step` spaced. The last element of the range +may not be `stop` in this case. -`length`, `stop`, and `step` cannot be all specified. +`length`, `stop`, and `step` cannot be all specified. An [`ArgumentError`](@ref) will be thrown. Special care is taken to ensure intermediate values are computed rationally. To avoid this induced overhead, see the [`LinRange`](@ref) constructor. @@ -95,6 +100,9 @@ julia> range(1, length=100) julia> range(1, stop=100) 1:100 +julia> range(1,stop=100, step=1) +1:1:100 + julia> range(1, stop=3.3) 1.0:1.0:3.0 From fbbbdf3b3c2203f29ab615d54114a00744b03c42 Mon Sep 17 00:00:00 2001 From: Mark Kittisopikul Date: Mon, 5 Oct 2020 03:16:32 -0400 Subject: [PATCH 03/10] Apply suggestions from code review by dkarrasch range doc: grammatical and formatting corrections Co-authored-by: Daniel Karrasch --- base/range.jl | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/base/range.jl b/base/range.jl index cd077333f4298..85a9a1bf6323e 100644 --- a/base/range.jl +++ b/base/range.jl @@ -75,7 +75,7 @@ Specifying a `step` of 1 explicitly, does not result in a [`UnitRange`](@ref). `stop` may be specified as either a positional or keyword argument. If `stop` is given as a positional argument, a keyword argument of either `length` or `step` must be specified. -If `stop` is given as the sole keyword argument, a `step` is assumed be 1.0. +If `stop` is given as the sole keyword argument, `step` is assumed to be 1.0. 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. @@ -100,7 +100,7 @@ julia> range(1, length=100) julia> range(1, stop=100) 1:100 -julia> range(1,stop=100, step=1) +julia> range(1, stop=100, step=1) 1:1:100 julia> range(1, stop=3.3) @@ -129,7 +129,6 @@ ArgumentError("Too many arguments specified; try passing only one of `stop` or ` julia> try range(1; stop=5, length=5, step=1) catch e println(e) end ArgumentError("Too many arguments specified; try passing only one of `stop` or `length`") - ``` """ range(start; length::Union{Integer,Nothing}=nothing, stop=nothing, step=nothing) = From ae01d597a4163aec85cc62f9ae3727e687f0dfcb Mon Sep 17 00:00:00 2001 From: Mark Kittisopikul Date: Mon, 5 Oct 2020 06:06:59 -0400 Subject: [PATCH 04/10] range: Create Extended help --- base/range.jl | 110 ++++++++++++++++++++++++++------------------------ 1 file changed, 58 insertions(+), 52 deletions(-) diff --git a/base/range.jl b/base/range.jl index 85a9a1bf6323e..7c39461130048 100644 --- a/base/range.jl +++ b/base/range.jl @@ -47,61 +47,33 @@ function _colon(start::T, step, stop::T) where T end """ - range(start; stop) - range(start; length) - range(start, stop; length) - range(start, stop; step) - - # The following cause an ArgumentError to be thrown. - range(start, stop) # Must specify either length or step - range(start; step) # Cannot specify step alone - range(start, stop; length, step) # Cannot specify all of stop, length, and step - range(start; stop, length, step) # Cannot specify all of stop, length, and step - -Given a starting value, construct an iterable with the first element of `start`. -One keyword argument of either `length`, `stop`, or `step` is required to avoid -ambiguity. - -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). + range(start[, stop]; length, stop, step) -`stop` may be included as the last element of the iterable depending on `step`. -`stop` may be specified as either a positional or keyword argument. -If `stop` is given as a positional argument, a keyword argument -of either `length` or `step` must be specified. -If `stop` is given as the sole keyword argument, `step` is assumed to be 1.0. +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. +`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. -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. +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. -`length`, `stop`, and `step` cannot be all specified. An [`ArgumentError`](@ref) will be thrown. - -Special care is taken to ensure intermediate values are computed rationally. -To avoid this induced overhead, see the [`LinRange`](@ref) constructor. +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(1, stop=100, step=1) -1:1:100 +julia> range(4, stop=100, step=2) +4:2:100 julia> range(1, stop=3.3) 1.0:1.0:3.0 @@ -118,18 +90,52 @@ julia> range(1, 10, length=101) julia> range(1, 100, step=5) 1:5:96 -julia> try range(1, 5) catch e println(e) end -ArgumentError("At least one of `length` or `step` must be specified") +julia> julia> range(1,5) +ERROR: ArgumentError: At least one of `length` or `step` must be specified +[...] -julia> try range(1, step=1) catch e println(e) end -ArgumentError("At least one of `length` or `stop` 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` +[...] +``` -julia> try range(1, 5; length=5, step=1) catch e println(e) end -ArgumentError("Too many arguments specified; try passing only one of `stop` or `length`") +# Extended help -julia> try range(1; stop=5, length=5, step=1) catch e println(e) end -ArgumentError("Too many arguments specified; try passing only one of `stop` or `length`") -``` + range(start; stop) + range(start; length) + range(start; stop, length) + range(start; stop, step) + range(start; length, step) + range(start, stop; length) + range(start, stop; step) + +The above forms of `range` are the only acceptable calls. + +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). + +`stop` serves only as an upper bound and may be included as the last element. +If `stop` is given as a positional argument, a keyword argument +of either `length` or `step` must be specified. +If `stop` is given as the sole keyword argument, `step` is assumed to be 1.0. + +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. The last element of the range +may not be `stop` in this case. + +`length`, `stop`, and `step` cannot be all specified. An [`ArgumentError`](@ref) will be thrown. + +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) From 3d0e3e8f8f8e840bacbdc772982acfc082fd4242 Mon Sep 17 00:00:00 2001 From: Mark Kittisopikul Date: Mon, 5 Oct 2020 06:08:48 -0400 Subject: [PATCH 05/10] range doc: Eliminate trailing white space --- base/range.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/base/range.jl b/base/range.jl index 7c39461130048..79bd5905d780c 100644 --- a/base/range.jl +++ b/base/range.jl @@ -55,8 +55,8 @@ Construct at an `AbstractRange`, given a starting value and one or two required elements of range. `step` is the difference between each element of the range. 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. +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. See the Extended help for more details. From 075e529e97975bed90a3aa3f3bbad1bf4a1eb001 Mon Sep 17 00:00:00 2001 From: Mark Kittisopikul Date: Mon, 5 Oct 2020 06:15:20 -0400 Subject: [PATCH 06/10] range doc: Expand calling syntax for clarity --- base/range.jl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/base/range.jl b/base/range.jl index 79bd5905d780c..2f95906da3911 100644 --- a/base/range.jl +++ b/base/range.jl @@ -47,8 +47,10 @@ function _colon(start::T, step, stop::T) where T end """ - range(start[, stop]; length, stop, step) - + range(start; stop, length) # any one keyword, creates a UnitRange (step = 1) + range(start, stop; length, step) # any one keyword + range(start; stop, length, step) # any two keywords + Construct at an `AbstractRange`, given a starting value and one or two required keyword arguments. `start` is the first value of range. `stop` is the upper bound of the range. `length` is the number of From 372e16a444b55da2454cd168dd4baf11426a9228 Mon Sep 17 00:00:00 2001 From: Mark Kittisopikul Date: Mon, 5 Oct 2020 06:17:07 -0400 Subject: [PATCH 07/10] range doc: Remove whitespace --- base/range.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/range.jl b/base/range.jl index 2f95906da3911..0ad8924422226 100644 --- a/base/range.jl +++ b/base/range.jl @@ -50,7 +50,7 @@ end range(start; stop, length) # any one keyword, creates a UnitRange (step = 1) range(start, stop; length, step) # any one keyword range(start; stop, length, step) # any two keywords - + Construct at an `AbstractRange`, given a starting value and one or two required keyword arguments. `start` is the first value of range. `stop` is the upper bound of the range. `length` is the number of From d3b6f7f4c156df3674d7d802acf5a83344134fbc Mon Sep 17 00:00:00 2001 From: Mark Kittisopikul Date: Mon, 5 Oct 2020 18:28:03 -0400 Subject: [PATCH 08/10] range doc: Remove reference to UnitRange in header --- base/range.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/range.jl b/base/range.jl index 0ad8924422226..2e513505a42b6 100644 --- a/base/range.jl +++ b/base/range.jl @@ -47,7 +47,7 @@ function _colon(start::T, step, stop::T) where T end """ - range(start; stop, length) # any one keyword, creates a UnitRange (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 From 58e80d917ccb7a5fd9e2d1f957eb148eef3ec043 Mon Sep 17 00:00:00 2001 From: Mark Kittisopikul Date: Mon, 5 Oct 2020 18:57:42 -0400 Subject: [PATCH 09/10] range doc: Added equation, structure in ext. help --- base/range.jl | 65 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 49 insertions(+), 16 deletions(-) diff --git a/base/range.jl b/base/range.jl index 2e513505a42b6..1cd2a8ffdf9c3 100644 --- a/base/range.jl +++ b/base/range.jl @@ -102,39 +102,72 @@ ERROR: ArgumentError: Too many arguments specified; try passing only one of `sto ``` # Extended help - - range(start; stop) range(start; length) + range(start; stop) + range(start; stop, length) - range(start; stop, step) - range(start; length, step) range(start, stop; length) + + range(start; stop, step) range(start, stop; step) -The above forms of `range` are the only acceptable calls. + range(start; length, step) -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)` +The above forms of `range` are the only acceptable forms of the range call. -Specifying a `step` of 1 explicitly, does not result in a [`UnitRange`](@ref). +## 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 a positional argument, a keyword argument -of either `length` or `step` must be specified. 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. +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`, `stop`, and `step` cannot be all specified. An [`ArgumentError`](@ref) will be thrown. + +### `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. From 20b84f401c15653c0ae303118a7c7dd47cd1cf1c Mon Sep 17 00:00:00 2001 From: Mark Kittisopikul Date: Mon, 5 Oct 2020 19:14:52 -0400 Subject: [PATCH 10/10] range doc: Remove whitespace --- base/range.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/base/range.jl b/base/range.jl index 1cd2a8ffdf9c3..1d67bafa9fb0e 100644 --- a/base/range.jl +++ b/base/range.jl @@ -111,7 +111,7 @@ ERROR: ArgumentError: Too many arguments specified; try passing only one of `sto range(start; stop, step) range(start, stop; step) - range(start; length, step) + range(start; length, step) The above forms of `range` are the only acceptable forms of the range call. @@ -145,7 +145,6 @@ If `step` and `stop` are provided and `length` is not, the overall range length 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