The rules for the list built-ins (Feel.Analysis.Images, D-161, step C): the 24 functions of Feel.Builtin.List.
A rule gives the whole type of the result from the types of the arguments, Null included, and is held to the run
(Feel.ImageCheck, test/feel/analysis/images/list_test.exs). What a rule builds on is the way an argument is a list
(section 10.3.2.9.4): a list is itself, a value that is not one is the list of it, and null is no list, so the call is
null. The type of an argument is read as that (read/1): the types of its elements, and how many it has, which is none
(empty list), one (a value that is not a list), one or more (non-empty list<...>, D-152), or any number.
| Function | The type of the result |
|---|---|
count | 0 for the empty list, 1 for a value that is no list, [1..max] for a list that has an element; never null for a list |
reverse, distinct values | the same elements, and the list that has an element stays one |
flatten | the elements of the lists among the elements, to a depth of 16; has an element if no element can be a list |
append, concatenate, union | the elements of the arguments, and of the items; has an element if an item is put in or an argument has one |
insert before, list replace, sublist | a list that has an element: a position that is right for a list is one for a list that has an element |
remove | the elements of the list (a list of one item has none left); [] for a value that is no list |
sort, list replace with a function | the elements of the list, the same number of them |
index of | list<number in [1..max]>, the empty list if nothing can be equal |
list contains | boolean, false if nothing can be equal or the list is empty |
sum, mean, median, product | a number (the item itself for a value that is no list; a + b for sum(a, b), and so on, with the sets) |
stddev | a number from 0 on; always null for a list, which may have fewer than two items |
mode | the list of the numbers, with an element if the list has one |
max, min | an element of one ordered kind (D-152), or Null |
all, any | the booleans that the items allow |
When the call is null
A null is in the type only if some arguments of the types give it (D-161):
- the argument that is a list is
null, or is the empty list where the function needs an item (sum([]),max([]),insert before([], 1, x),stddev([x])); - an item is not of the kind the function wants (
sum(["a"]),all([1]),max([1, "a"]), anullamong the numbers,[true, null]forall); - a position that is not right for a list:
0, past the end,null, or not a number. A list has any length and a type does not say it, so a position is right for every list that has an element only if it is cut to1or-1(a fraction is cut off toward zero:[1..2)and(-2..-1]); one that is cut to0is right for none. Asublistof a length takes it in the same way, and the length that is right for every list is1; - the arithmetic of the numbers fails (see below);
- a function argument (
sort,list replace) that is not a function of two parameters that gives a boolean.
Callback acceptance uses observable runtime arrows, not call refinements. These arrows guarantee signatures, but do not exhaust them: a three-argument function type can hold a value that also has a two-argument Boolean signature. Without such a guaranteed signature, a function remains a possible callback and possible rejection. An excluded function is classified through its positive base.
The arithmetic of a list of numbers
The count of a list is not in its type, so the sums and products of a list are those of lists of every length up to
@most_items (1E+18, what Feel.Builtin.Arguments calls past the end of anything a run can build):
sumoverflows if 1E+18 times the largest number, or the least, is out of range: the list of the largest number twice does, and no list of[0..150]does.meanis the sum, and a division by the count, which isnullfor a result too small to write (D-161): when the total can be near zero and not zero. Numbers are multiples of 1E-6176, so the mean of0and1E-6176isnull, as is that of-1,1and1E-6176; a set of numbers that stay away from zero ([0.001..150]) never is.medianof an even count is the mean of the two in the middle: the sum of two, and the division by 2.productof a list overflows or is too small to write unless all the numbers are-1,0or1.stddevof two items or more isnullfor a sum or a square out of range, and for the square of a difference too small to write, which an item near zero has when the mean is near zero too.
The sets of the numbers are kept for what is exact and the kind is the type of the rest, which is broader and so sound: the
set of the sum of a list is not worked out, that of a few items given as arguments is (sum(a, b) is a + b, mean(a, b)
the sum divided by 2). The search for the arithmetic that fails is by the bounds and the neighbourhood of zero of the sets,
and is broader than the run for sets that are not intervals of numbers away from zero (it may say Null for a set of one
number near zero, which no list gives), never narrower.