Auto functions

Some functions can have their bodies generated automatically.

main void() a strings = ("a", "b") distinct b strings = (2, "a") repeat info log "{a == a} {a == b}" info log "{a <=> b}" info log "{a.to::json} {b.to::json}" strings union distinct string[] repeat string repeat == bool(a strings, b strings) <=> comparison(a strings, b strings) to json(a strings) repeat[t] record count nat value t ==[t] bool(a t repeat, b t repeat) t equal <=>[t] comparison(a t repeat, b t repeat) t compare to[t] json(a t repeat) (json, t) to

Currently supported auto functions are:

Function Result for union Result for record
== True if the arguments chose the same union member and the member values are equal. True if all corresponding fields are equal.
<=> Members declared first compare less.
For the member, compare the values.
Compares each field in order.
to json A JSON object with one key for the chosen member. A JSON object with one key for each record field.

In order to generate an auto function, it function must be implemented for each member type.
For example, == for strings depends on == implementations for string[] and string repeat.
The member's implementation can be a spec, as in to[t] json(a t repeat) (json, t) to.

An auto function doesn't have to be declared next to the type, but it won't work if some of the type's members aren't visible at the declaration of the auto function.