Narrowing › range. The names in the examples are those of section 2.
A range alternative is {:range, endpoint}, where endpoint is a union: range<number>. A range value is a Feel.Value.Range (D-61), made by a literal such as [1..10) or a prefix test used as a value such as (< 10). It has no value set of its own: the type does not say which endpoints a range has. So a fact about a range can say only whether it is null, what its endpoint type is, and what shape it has when it is compared with another range.
A range value in a name
| Condition | r when true | r when not true |
|---|---|---|
r = null | Null | range<number | Null> |
r != null | range<number | Null> | Null |
r instance of range<number> | range<number | Null> | Null |
r instance of range<string> | range<Null> | range<number | Null> except range<string | Null> | Null |
range<number> is a range whose endpoints are numbers or null; range<Null> is a range of nothing but null endpoints, which is also a range<string>. Equality of two ranges is read as the equality of two lists is: part by part (D-194), against a type that is known.
| Condition | v when true | v when not true |
|---|---|---|
v instance of range<number> | range<number | Null> | Any except range<number | Null> | Null |
A range in an in is not a range value
x in [1..10] is not a test against a range value. A range written in an in, or in a list of unary tests, is the two comparisons it says: x >= 1 and x <= 10, with the open and closed ends as written (D-61, D-194). That is why it narrows x exactly (number), while a range held in a name does not: the test cannot be read until run time, and a test that is a value rather than a comparison says nothing.
| Condition | x when true | x when not true |
|---|---|---|
x in [1..10] | number in [1..10] | number in [-max..1), (10..max] | Null |
x in r | number | Null | number | Null |
The built-ins that relate a point and a range (includes(r, x), before(x, r), …) are functions, and give no fact:
| Expression | Type | Warnings |
|---|---|---|
if includes(r, x) then x else null | number | Null | — |
The functions of points and ranges
before, after, coincides, during, finished by, finishes, includes, meets, met by, overlaps, overlaps after, overlaps before, started by and starts give true or false, and null for an argument that is out of the domain (D-79). The type says which of the three a call is (Feel.Analysis.Images.Range, D-170):
- Two points of one kind are compared by their sets.
before(a, b)isa < b,afterisa > bandcoincidesisa = b:before(n, 100)istruefor annin[0..10]. Two points of kinds that cannot be compared (a number and a string, a date and a date and time) arenullfor sure, and two times, or two dates and times, can benull. - A range is not looked into. Its type has the kinds of its endpoints and not the endpoints, and has the range with no endpoint, which is related to anything: the call is a
boolean, andnullwhere an endpoint of one can be of a kind that cannot be compared with one of the other (before(s, r)for a string and arange<number>). nullis among the alternatives only for anullargument, a list that does not have exactly one item, a value that is neither a point nor a range, and a combination that is not a signature (meets(1, 2)).
| Expression | Type | Warnings |
|---|---|---|
before(k, k) | boolean | — |
before(x, k) | boolean | Null | — |
before(k, s) | Null | — |
if n != null then before(n, 100) else null | boolean = true | Null | — |
if r != null then includes(r, k) else true | boolean | — |
if r != null then before(s, r) else true | boolean | Null | — |
meets(k, k) | Null | argument_out_of_domain |
Limits
- No value set: a range's endpoints are not in its type.
- An endpoint that can be
nullis the comparison withnullthat the run makes (D-61), so it is read as the run does.
See also: number, list, overloaded functions (the point and range relations).