The rules for the conversion functions (Feel.Analysis.Images, D-170; Feel.Builtin.Conversion): date, date and time,
duration, number, range, string, time and years and months duration.
A rule gives the whole type of the result, Null included, from the types of the arguments. Each argument is read for the
kinds the parameter takes, and whether the call is null for it: null, a value of another kind, a list of any other
length than one (a list of one is its item, section 10.3.2.9.4; string takes the list as it is), and a value of a type
that is not known. Then the result is found in one of two ways, from the exact to the kind:
- The function is run on the values of a finite set. The strings of a list (
{"1", "x"}), the numbers that are single, and the booleans give the values of an argument, and the function itself (Feel.Builtin.call/3) is called on every combination of them, up to 64:number(s)for{"1", "2.5"}is{1, 2.5},number(s)for{"1", "x"}is the number1orNull,date(s)for{"2021-01-31"}is a date, andstring(n)for{1, 2}is{"1", "2"}. A call that passes a limit of the run ends it and has no value, and then the kind answers. - The kind, and what the types say of the rest. A number is itself for
number, a date fordate, a time fortime; the date of a date and time is a date, and its time a time; a string is a value of the kind orNull, since a string that is none exists; and a number outside what a date or a time takes (a month 13, a second 60) isNull.
What is null
Null is in the type only if some arguments make the run give it. That is a null argument and an argument of another kind,
and a string that is none of the kind (date(s) for any string), and what the function turns down of the right kinds:
| Function | null for |
|---|---|
date(year, month, day) | a year past ±999,999,999, a month not in 1..12, a day not in the month (the fraction of each is cut off) |
time(hour, minute, second[, offset]) | an hour not in 0..23, a minute not in 0..59, a second not in [0..60), an offset that is not whole seconds within 14 hours |
date and time(date, time, timezone) | a time that has a zone, a zone that is none |
string(from) | null, a function, and a list or a context that has one |
date and time(date, time), years and months duration | nothing |
Where the days of a month are in question, a day past the 28th is taken to be null for some month, which is so when the set
of months and years has a month that does not have it; the type is then a superset.