a:b colons (:) used as a binary infix operator construct a range from a to b (inclusive) with fixed step size 1 Punctuation · The Julia Language
I expected the second output to be 5:1, ie [5, 4, 3, 2, 1]. Ok, I can see that reading carefully the stepsize is 1, when I wanted -1. But why does it say 5:4? And why not have it automatically switch the sign if a > b?
Has adding a note about this to the docs been considered?
You pretty much answered your own question on why it’s not equal to [5,4,3,2,1]: it’s because that’s not its definition. Yes, that’s tautological. Steven has a good motivation for the current behavior, but a different choice could have been made.
Julia “normalizes” empty ranges such that the end is one step less than the beginning, so that’s why it’s 5:4 and not 5:1. Why? IIRC it helps with some efficiencies for all ranges, even non-empty ones, if you can assume that.
Take a look at the function range and the rules become clearer. If you specify only start and stop the step is assumed to be 1.
help?> range
search: range LinRange UnitRange StepRange StepRangeLen
range(start, stop, length)
range(start, stop; length, step)
range(start; length, stop, step)
range(;start, length, stop, step)
Construct a specialized array with evenly spaced elements and
optimized storage (an AbstractRange) from the arguments.
Mathematically a range is uniquely determined by any three of
start, step, stop and length. Valid invocations of range are:
• Call range with any three of start, step, stop,
length.
• Call range with two of start, stop, length. In this
case step will be assumed to be one. If both
arguments are Integers, a UnitRange will be
returned.
• Call range with one of stop or length. start and
step will be assumed to be one.
With the colon syntax, you can specify start:step:stop.
An empty range could be expressed as 5:1:4 (i.e. by explicitly specifying a positive step size)
I think there are a few different points to this topic.
Definition/characteristics of ranges (start, length, stop, step)
Why are empty ranges “normalised”
What are default values for under-specified ranges, in particular using colon syntax.
In some contexts, I think it would be reasonable to expect differing defaults for when a range is under-specified. When start and stop are explicitly specified with literals (e.g. 3:7, 5:1), I don’t think it is unreasonable to expect a default step size of +/-1 to make a non-empty range.
However, personally I do like the current default step size of +1 (allowing empty ranges), because it simplifies the following type of logic of iterating through 0 or more items:
No, because then m:step:n would not be type stable. Julia uses a separate UnitRange type to represent m:n ranges (in which the step size is implicitly 1), in order to save 1/3 of the storage in this common case and to enable other optimizations.