// // mapValues // function mapValues; overload mapValues('f, 'first, ...'rest) = f('first), ...mapValues('f, ...'rest); overload mapValues('f) = ; // // clay types as symbols // symbol Bool; symbol Int; symbol Array['T, 'n]; symbol Tuple[...'T]; symbol RecordTag; recordType(...'fields) = (RecordTag, fieldNames(...'fields), fieldTypes(...'fields)); fieldNames(...'fields) = (...mapValues(f => tupleElement(f, 0), ...'fields)); fieldTypes(...'fields) = (...mapValues(f => tupleElement(f, 1), ...'fields)); record?('t) = symbolWithBody?('t) and tupleWithTag?(symbolBody('t), RecordTag); symbolWithBody?('x) = symbol?('x) and symbolHasBody?('x); tupleWithTag?('x, 'tag) = tuple?('x) and lesser?(0, tupleSize('x)) and equals?(tupleElement('x, 0), 'tag); recordFieldCount('t) | record?('t) = tupleSize(tupleElement(symbolBody('t), 1)); recordFieldNames('t) | record?('t) = tupleElement(symbolBody('t), 1); recordFieldTypes('t) | record?('t) = tupleElement(symbolBody('t), 2); symbol Point['T] = recordType( ("x", 'T), ("y", 'T), ); recordInfo('t) | record?('t) = ('t, recordFieldNames('t), recordFieldTypes('t)); main() = recordInfo(Point[Int]);