// Schema Evolution Demo // Demonstrates version tracking in the type system // ============================================================ // PART 1: Basic Version Annotations // ============================================================ // Functions can require specific versions of data fn processV1Data(value: Int @v1): Int = value * 2 fn processV2Data(value: Int @v2): Int = value * 3 // Version-annotated values let dataV1: Int @v1 = 100 let dataV2: Int @v2 = 100 // These work - versions match let resultV1 = processV1Data(dataV1) // 200 let resultV2 = processV2Data(dataV2) // 300 // ============================================================ // PART 2: Version Constraints // ============================================================ // @v2+ means "version 2 or later" fn processModernData(value: Int @v2+): Int = value + 1 // This works - v2 satisfies v2+ let modernResult = processModernData(dataV2) // @latest means "compatible with any version" fn processAnyVersion(value: Int @latest): Int = value // This works - @latest accepts any version let anyResult = processAnyVersion(dataV1) // ============================================================ // PART 3: Runtime Schema Operations // ============================================================ // Create versioned values at runtime let user1 = Schema.versioned("User", 1, { name: "Alice", role: "admin" }) let user2 = Schema.versioned("User", 2, { name: "Bob", role: "user", active: true }) // Check versions let v1 = Schema.getVersion(user1) // 1 let v2 = Schema.getVersion(user2) // 2 // Migrate to newer version (upgrade) let upgraded = Schema.migrate(user1, 2) let upgradedVersion = Schema.getVersion(upgraded) // 2 // ============================================================ // PART 4: Practical Example - API Versioning // ============================================================ // Simulate different API response versions fn createResponseV1(data: String): { version: Int, payload: String } = { version: 1, payload: data } fn createResponseV2(data: String, timestamp: Int): { version: Int, payload: String, meta: { ts: Int } } = { version: 2, payload: data, meta: { ts: timestamp } } // Version-aware processing fn getPayload(response: { version: Int, payload: String }): String = response.payload let resp1 = createResponseV1("Hello") let resp2 = createResponseV2("World", 1234567890) let payload1 = getPayload(resp1) let payload2 = getPayload(resp2) // ============================================================ // RESULTS // ============================================================ fn main(): Unit with {Console} = { Console.print("=== Schema Evolution Demo ===") Console.print("") Console.print("Part 1: Version-specific processing") Console.print(" processV1Data(100 @v1) = " + toString(resultV1)) Console.print(" processV2Data(100 @v2) = " + toString(resultV2)) Console.print("") Console.print("Part 2: Version constraints") Console.print(" processModernData(@v2+) = " + toString(modernResult)) Console.print(" processAnyVersion(@latest) = " + toString(anyResult)) Console.print("") Console.print("Part 3: Runtime schema operations") Console.print(" User v1 version: " + toString(v1)) Console.print(" User v2 version: " + toString(v2)) Console.print(" After upgrade: " + toString(upgradedVersion)) Console.print("") Console.print("Part 4: API versioning") Console.print(" Response v1 payload: " + payload1) Console.print(" Response v2 payload: " + payload2) } main()