Records and Tuples
2025 and beyond
Previously: 2024-04 "Discussing new directions"
typeof #{x: 10, y: 20} // "record"�
typeof #[1, 2, 3] // "tuple"
#{x: 0, y: 20} === #{x: -0, y: 20}�
#[1, 2, 3] === #[1, 2, 3]
A design I really like
Has Syntax
#{a: 1, b: #[2, 3]}�vs �f({a: 1, b: f([2, 3])})
Has Syntax - static guarantees
export const config = #{
pages: #{
size: 10
}
};
�
import { config } from "./config.js";
get(config.pages.size); // 'guaranteed' 10
Has Syntax
Are Objects
typeof #{} === "object"
Array.isArray(#[])�
Shallow immutability
Object.isFrozen(#[])�#[new PlainDate(2025,2,18), new PlainDate(2025,2,20)]
Deep immutability alternative
R&T
SharedStructs
Symbols
JSON
acyclic
BigInt
undefined
writable
Deep immutability alternative
#{ __proto__: vector2DProto, x, y }
new PlainDate(2025,2,18).toRecord()
immutability
shallow
deep
flexibility
guarantees
Composite Keys�or how immutable data structures are wonderful for equality
Composite Keys
Map.groupBy(arr, obj => obj.x) ✅��Map.groupBy(arr, obj => [obj.x, obj.y]) 🔴�Map.groupBy(arr, obj => `${obj.x}:${obj.y}`) 🟠�
Composite Keys
Map.groupBy(arr, obj => obj.x) ✅��Map.groupBy(arr, obj => [obj.x, obj.y]) 🔴�Map.groupBy(arr, obj => `${obj.x}:${obj.y}`) 🟠�Map.groupBy(arr, obj => key(obj.x, obj.y)) 🟢
Composite Keys in the wild - interning
key(objA, objB, 1n, "abc") === key(objA, objB, 1n, "abc")
Weak K | V |
objA | |
… | … |
Weak K | V |
objB | |
… | … |
K | V |
1n | |
… | … |
K | V |
"abc" | W<🔑> |
… | … |
FinalizationRegistry
Composite Keys in the wild - interning
Composite Keys
Map.groupBy(arr, obj => obj.x) ✅��Map.groupBy(arr, obj => [obj.x, obj.y]) 🔴�Map.groupBy(arr, obj => `${obj.x}:${obj.y}`) 🟠�Map.groupBy(arr, obj => key(obj.x, obj.y)) 🟢�Map.groupBy(arr, obj => #[obj.x, obj.y]) 👀
Composite Keys
Composite Keys
Composite Keys
Composite Keys
Let's discuss