// // 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), ); [record?('t)] recordInfo('t) = ('t, recordFieldNames('t), recordFieldTypes('t)); main() = recordInfo(Point[Int]);