Ranges

A range represents some span over a set of values. Typically ranges will be over numbers, however any orderable set could be used for a range (e.g. strings, dates, etc.). Ranges are frequently used for loops, indexing, and several other places.

Ranges always contain a .. and may include left and or right values that are juxtaposed, optionally specifying the bounds and step size.

Range Syntax

The syntax for ranges is inspired by Haskell syntax for ranges:

Like in haskell, you can use a tuple to include a second value to specify the step size.

Note: [first..2ndlast,last] is explicitly NOT ALLOWED, as it can have unintuitive behavior, and is covered by [first,second..last].

In addition, ranges can have their bounds be inclusive or exclusive. Inclusive bounds are indicated by square brackets, and exclusive bounds are indicated by parenthesis. The default is inclusive bounds. Also left and right bounds can be specified independently, so you can have a range that is inclusive on the left and exclusive on the right, or vice versa.

Juxtaposition

The left and right values are only considered part of the range if they are juxtaposed with the ... Values not juxtaposed with the range are considered separate expressions.

Note: the range juxtaposition operator has a quite low precedence. Most operators will have higher precedence, meaning the left and right expressions don't need to be wrapped in parenthesis. However, due to range juxtapose's low precedence, any range as part of an in expression (e.g. a in [A..B]) must be wrapped in range bounds (i.e. [], (], [), ()) to ensure the range is parsed correctly. a in A..B will be parsed as (a in A)..B .

Multiple ranges can be used to index into multidimensional matrices

Numeric Ranges

Probably the most common type of range will be a numeric ranges which describes a span over real numbers.

Some simple examples include:

Ordinal Ranges

Ranges can also be constructed using any ordinal type. Currently the only only built in ordinal type other than numbers would be strings.

For example, the following range captures all characters in the range from 'a' to 'z' inclusive

All alphabetical characters might be represented like so

But I probably won't just be limited to individual characters. In principle you ought to be able to do something like this

which would create a range that consists of every possible 5 letter combination starting from the word 'apple' and iterating through to the word 'zebra'.

Note: this is distinct from every dictionary word in that range, as it will include many many gibberish words.

TDB exactly what criteria will be used for ordering strings, as I like string orderings that respect numbers embedded in them (e.g. 'apple2' should come before 'apple10'), but that becomes difficult with arbitrary strings. perhaps there might be a macro setting for the ordering type used

Range Uses

Ranges have a variety of different uses in Dewy.

Ranges in Loops

Probably the most common use is in conjunction with loops as a sequence to iterate over:

The above will print '0 1 2 3 4 5 '.

To iterate over values in reverse, you can specify a reversed range:

This prints '5 4 3 2 1 0 '.

Note: when specifying a reversed range, you must include the step size. Forgetting to specify the step size will result in an empty range, as ranges are normally increasing.

Range Arithmetic

Ranges can be used in arithmetic expressions, often as a way to construct new ranges.

Both of which will print '0 0.25 0.5 0.75 1 '

These are both equivalent to directly constructing the range [0,0.25..1], however the arithmetic versions are frequently more convenient.

This type of construction is closely related to the linspace()/logspace() functions in Dewy. TBD but linspace/logspace may in fact be implemented like so:

Compound Range Construction

Additionally you can construct more complex ranges by combining together multiple ranges:

The same range as above can be constructed using subtraction

Interval Membership

You can also check if a value falls within a specified range

Indexing Sequences

ranges can be used to select values from a sequence. For example, say we want a substring we can do the following

This works for any sequence type.

Note: only integer ranges can be used to index into sequences (TBD if this might be relaxed to real valued ranges).

Also, because array access is a juxtapose expression, we can easily make the selection inclusive or exclusive on either side.

You can specify that a range continues to the end of the sequence, or starts from the beginning by omitting the value for that side. This will construct a range that goes to infinity in that direction, which will select all elements in that direction.

Paired with the special end token which represents the index of the last element in a sequence, this provides the means to select any desired subset of a sequence.