We've already seen a great deal of examples using ranges so far, but I thought it would be good to go into detail regarding ranges.

A range represents a sequence of numbers, and it is defined using a low bound and a high bound, both of which are inclusive. Both bounds are separated by two dots. So the range 1 to 10 looks like 1..10. This is the equivalent to the list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]. A range is far more memory efficient than a list of sequential numbers because it just needs to store two integers: the low bound and the high bound.

Ranges are enumerable, and each element in the range is generated as the range is iterated over. There's no need to store every number in a range when it can be generated. As we've seen from previous coverage of the Enum module, any Enum function can be used on a range.

A range can be defined using a literal or it can be defined using variables.

iex> 1..10
1..10
iex> low = 15
15
iex> high = 50
50
iex> low..high
15..50
iex> low..20
15..20
iex> -50..high
-50..50

A range doesn't always have to be in ascending order either. You can specify a range that will be enumerated in descending order.

iex> 100..1
100..1
iex> 10..-22
10..-22
iex> Enum.to_list(10..-10)
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10]

There is no equivalent to a range in the Javascript language. The lodash library has a range function that looks like _.range(1, 5), but that returns an array with the numbers in that range. There's no data structure that represents an enumerable range that generates integers as needed. However, you could probably write a generator function that would generate the individual numbers in a range, and it wouldn't surprise me if some Javascript library has already implemented that.

C# does not have ranges as an integral part of the language, but the LINQ extensions in the C# standard libaries can be used to create a range enumerable whose values will be generated as it is iterated over. An IEnumerable<int> can be created using Enumerable.Range(1, 5). Since the integers aren't generated until they are enumerated, this is an equivalent to a range.

IEnumerable<int> range = Enumerable.Range(1, 5);

//The range is enumerated and result is {1, 2, 3, 4, 5}
List<int> rangeElements = range.ToList();

If you've been following along with me this whole time, you've probably picked up most of this along the way. If not, then this discussion of ranges was worth it.