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

Doc PR to clarify range usage #37875

Closed
wants to merge 10 commits into from
60 changes: 52 additions & 8 deletions base/range.jl
Original file line number Diff line number Diff line change
Expand Up @@ -47,23 +47,48 @@ 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)).
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

step does not default to 1 when length is specified.

step does not default to 1 when stop is a positional argument. range(1,5) does not work but range(1,5, step=1) does.

The only time step defaults to 1 is when using stop as a positional argument: range(1,stop=5)

One of `length` or `stop` is required. If `length`, `stop`, and `step` are all specified, they must agree.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If length, stop, and step are all specified, they must agree.

length, stop, and step cannot be all specified:

julia/base/range.jl

Lines 166 to 167 in 01d89c6

_range(start::Real, step::Real, stop::Real, length::Integer) = # range(a, step=s, stop=b, length=l)
throw(ArgumentError("Too many arguments specified; try passing only one of `stop` or `length`"))

_range(start::Real, step::Real, stop::Real, length::Integer) = # range(a, step=s, stop=b, length=l)
    throw(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)

# 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

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we should always put the one-or-two-line description right after the function signature.

This can be moved backward in the Examples section.

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).

`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.
mkitti marked this conversation as resolved.
Show resolved Hide resolved

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.
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.

`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.

Expand All @@ -75,6 +100,12 @@ julia> range(1, length=100)
julia> range(1, stop=100)
1:100

julia> range(1,stop=100, step=1)
mkitti marked this conversation as resolved.
Show resolved Hide resolved
1:1:100

julia> range(1, stop=3.3)
1.0:1.0:3.0

julia> range(1, step=5, length=100)
1:5:496

Expand All @@ -86,6 +117,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")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alongside with the previous one comment, this could just be

# Must specify either length or step
julia> range(1, 5)
ERROR: ArgumentError: At least one of `length` or `step` must be specified

And the doctest only match the starts (if I get it correctly). For example, in OffsetArrays: https://github.com/JuliaArrays/OffsetArrays.jl/blob/87666ee004664282370122ba68e7467c13988b38/src/axes.jl#L12-L24

Reference: https://juliadocs.github.io/Documenter.jl/dev/man/doctests/#Exceptions


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`")

mkitti marked this conversation as resolved.
Show resolved Hide resolved
```
"""
range(start; length::Union{Integer,Nothing}=nothing, stop=nothing, step=nothing) =
Expand Down