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".
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.