Ranges and Ranged-Lists
Overview
The range operators in Nutmeg are a shorthand for writing out all the numbers from a starting value to a finishing value. So, instead of writing out all the numbers from 1 to 100 you could just write 1 ... 100
. Or you could pass them to an operator that accepted lots of arguments, like sum
:
sum( 1 ... 100 )
### Returns 5050
The other range operator is the "half-open" range, written ..<
. As the ‘<' suggests, it yields the all values from the start but does not include the finishing value. For example 0 ..< 5
will generate the values 0, 1, 2, 3, 4
but does not include 5
.
Combined with List Brackets
Ranges combine especially well with lists. In fact Nutmeg specially recognises the situation when a range is used inside a pair of brackets like this: [ 10 ... 15 ]
. This is the easiest way to create a special kind of list, called a ranged-list.
Ranged-lists are the simplest example of a procedural list. Procedural-lists do not expand out all their members, they just calculate their members on demand. If you have [low ... high]
and ask for the 3rd member, Nutmeg simply adds 3 to low. So the third member of 10 ... 15
would be 13, for example. This means that ranged-lists are very compact and efficient and so are all procedural lists in general.
Combined with Other Brackets
You can also use ranges with Nutmeg's other brackets, such as set brackets {? 0 ..< n ?}
, series brackets [% 0 ..< n %]
and even stream brackets [: 0 ..< n :]
. All of these will generate procedural collection-like-objects, so you can use large ranges without worrying about using lots of store.
Half-open or closed ranges - which is best?
Is it better to use closed-intervals with ...
or half-open intervals like ..<
? The computer scientist Dijkstra famously argued that half-open intervals are more natural. It has certainly persuaded a lot of language-designers that the first member of a list should be numbered 0 and not 1, somewhat counter-intuitively. Although we find Dijkstra's argument to be not entirely compelling, Nutmeg follows the same convention to avoid friction for when our coders switch from one language to another.
Because of this, you will find yourself using the half-open range 0 ..< n
much more often than 1 ... n
. It just fits better when lists start from 0. So it might feel a bit awkward at first but its worth getting used to.
Technical Summary
Ranges
Nutmeg has special syntax for two ranges:
A ..< B
generates the integer values from A to B, not including B.A ... B
generates the integer values from A to B, including B.
To generate other, more general ranges use the explicit Range
functions.
Range{ step = 1, test = nonfix < }( initial, final )
- returns an object that is both a list and a series whose first member isinitial
and whose (n+1)th member M is the nth member plusstep
. The series continues while thetest
is satisfied; the sign ofstep
determines the order of arguments. Ifstep >= 0
thentest( M, final )
is used, otherwisetest( final, M )
.
Ranged Lists
The expression [ A ..< B ]
is recognised as syntactic sugar for Range( A, B )
and [ A ... B ]
as syntactic sugar for Range{ test = nonfix <= }( A, B )
. Other brackets also yield procedural analogs e.g. {? A ..< B ?}
is synonymous with RangeSet( A, B )
.