A range is an immutable sequence of values
that increase “linearly” - i.e. by a fixed amount.
Most commonly it’s a sequence of consequtive integers.
An example of the syntax is [3 <: 7] which evaluates
to the sequence [3 4 5 6].
You can specify an explicit increment with a by: option.
There are multiple ways to specify when the sequence stops.
For example [3 by 2 <=: 7] is the even numbers from
3 up to 7 (inclusive, because of the <=).
Ranges are very useful for loop indexes, or selecting a sub-sequence.
If you have a sequence q and a range r, and you
use the syntax ( to
“apply”q r)q with the argument r,
is result is to select elements of q with indexes in r.
("ABCDEFG" [1 by: 2 <: 7]) ⇒ "BDF"
A range can be unbounded, or non-finite, if you leave off
the end value. For example [3 by: 2] is the odd integers starting at 3.
The expression [ evaluates to an
infinite sequence of values, starting with start by: step]start, and followed by
(+ ,
start step)(+ , and so on.
start (* 2 step))
The syntax [
is shorthand for start-expression <:][.
start-expression by: 1]
bounded-range ::= [ start-expression [by: step-expression] range-end ]
range-end ::= <: end-expression
| <=: end-expression
| >: end-expression
| >=: end-expression
| size: size-expression
A bounded range takes an initial subsequence of the unbounded
range specified by the start-expression and optional step-expression.
The different end-expression variants provide different
ways to specify the initial subsequence.
If size: is specified, then the resulting range
is the first sizesize elements of unbounded sequence.
In the <: or end<=: cases then
the sequence counts up: The endstep must be positive, and defaults to 1.
The resulting values are those x such that (< ,
or x end)(<= , respectively.
x end)
In the >: or end>=: cases then
the sequence counts down: The endstep must be negative, and defaults to -1.
The resulting values are those x such that (> ,
or x end)(>= , respectively.
x end)
The start-expression, step-expression, and size-expression
must evaluate to real numbers, not necessarily integers.
For example: [1 by: 0.5 <=: 3.0] is [1.0 1.5 2.0 2.5 3.0].
The two pseudo-ranges [<:] and [>:] are useful as
array indexes. They mean “all of the valid indexes” of the array being indexed.
For increasing index values use [<:]; for decreasing
index values (i.e. reversing) use [>:].