Ranges are finite numerical intervals, e.g. “all integers
i such that
(m <= i) and
(i < n)”. The high end bound is sometimes exclusive,
(i < n), and sometimes inclusive,
(i <= n).
In Wuffs syntax, similar to Rust syntax, the exclusive range is
m .. n and the inclusive range is
m ..= n. The conventional mathematical syntax is
[m, n) or
[m, n[ for exclusive and
[m, n] for inclusive, but Wuffs is a programming language, and programming language tools prefer brackets to always be balanced.
In Wuffs' C form, the exclusive range is
wuffs_base__range_ie_T and the inclusive range is
ie means inclusive on the low end, exclusive on the high end. The
T is a numerical type like
Both of the
ie flavors are useful in practice:
m ..= n is more convenient when computing interval arithmetic,
m .. n is more convenient when working with slices. The
ee flavors also exist in theory, but aren't widely used. In Wuffs, the low end is always inclusive.
ie (half-open) flavor is recommended by Dijkstra's “Why numbering should start at zero” and see also a further discussion of half-open intervals.
For example, with
ie, the number of elements in “
uint32_t values in the half-open interval
m .. n” is equal to
max(0, n - m). Furthermore, that number of elements (in one dimension, a length, in two dimensions, a width or height) is itself representable as a
uint32_t without overflow, again for
n. In the contrasting
ii flavor, the size of the closed interval
0 ..= ((1<<32) - 1) is
1<<32, which cannot be represented as a
In Wuffs' C form, because of this potential overflow, the
ie flavor has length / width / height methods, but the
ii flavor does not.
ii (closed) flavor is useful when refining e.g. “the set of all
uint32_t values” to a contiguous subset: “
uint32_t values in the closed interval
m ..= n”, for
n. An unrefined type (in other words, the set of all
uint32_t values) is not representable in the
ie flavor because if
((1<<32) - 1) then
(n + 1) will overflow.
It is valid for
m >= n (for the
ie case) or for
m > n (for the
ii case), in which case the range is empty. There are multiple valid representations of an empty range:
(m=1, n=0) and
(m=99, n=77) are equivalent.
Rects are just the 2-dimensional form of (1-dimensional) ranges. For example,
wuffs_base__rect_ii_u32 is a rectangle on the integer grid, containing all points
(x, y) such that
(min_incl_x <= x) and
(x <= max_incl_x), and likewise for
Once again, it is valid for
min > max, and there are multiple valid representations of an empty rectangle.
When rects are used in graphics, the X and Y axes increase right and down.