Show all entries

Tue 2022-12-13

Functional records

I added a data type for "records." A record behaves like a function that maps string keys to arbitrary values. It is represented internally as a vector of zero or more items, each item a {key val} pair, sorted by key.

The expression (empty) returns the empty record.

The expression (set key val obj) sets key to val in record obj, returning a record like obj but with key mapped to val. It modifies obj inline if there are no other references to it; otherwise it returns a modified copy of obj.

The expression (record_count obj) returns the number of items in the record.

The expression (record_item obj pos) returns the item in record obj at offset pos, starting at zero.

These functions can be used to define record_pairs, which returns the lazy list of pairs in a record, allowing iteration (see test/record.fxl).

I added a :: function, defined by type_chain in basic.c. The expression (:: a b x) returns (a x) if that value is defined, otherwise (b x). This is used to establish default values when a key is not defined in a record or other function. I refer to the :: function as "chain".

Examples

This constructs a simple record value:

(
set "a" 1;
set "b" 2;
set "c" 3;
set "d" 4;
set "e" 5;
empty
)

This overrides some of the earlier specified values:

(
set "c" 33; # maps "c" to 33 instead of 3
set "b" 22; # maps "b" to 22 instead of 2

set "a" 1;
set "b" 2;
set "c" 3;
set "d" 4;
set "e" 5;
empty
)

Here is the commit on GitHub. See test/record.fxl for more examples.