How do I migrate Swift enum associated values to EK9?
← Enumerations · Ref: Q746
Swift enums can carry data per variant (associated values). EK9 enums are pure value types with no fields or methods. The EK9 equivalent uses enum + Dict for data, or enum + class hierarchy for complex variants.
SWIFT PATTERN: ASSOCIATED VALUES
Swift lets each enum case carry different data:
enum Shape {
case circle(radius: Double)
case rectangle(width: Double, height: Double)
}
Swift extracts data via pattern matching in switch.
EK9 PATTERN 1: ENUM + DICT FOR SIMPLE DATA
When each variant maps to a single value, use a Dict:
defines type Colour: Red, Green, Blue labels <- {Colour.Red: "#FF0000", Colour.Green: "#00FF00", Colour.Blue: "#0000FF"}
This separates identity (enum) from data (Dict), keeping both independently testable and serialisable.
EK9 PATTERN 2: TRAIT HIERARCHY FOR COMPLEX VARIANTS
When variants carry different shaped data (like Swift's Shape example), use a trait with classes:
defines trait Shape area() as pure abstract <- rtn as Float? defines class Circle with trait of Shape radius <- 0.0 override area() as pure <- rtn as Float: 3.14159 * radius * radius Rectangle with trait of Shape ...
Each class carries its own data. The trait defines the shared contract.
WHY COMPOSITION IS SUPERIOR
Swift's associated values tightly couple identity and data. EK9's separation gives:
- Serialisability: enums convert to JSON automatically, associated values need custom Codable
- Testability: functions and Dict entries are independently testable
- Extensibility: add new data mappings without modifying the enum
- Quality: the compiler enforces metrics on each function independently
See Q100 for enum vs Java comparison. See Q219 for auto-generated operators. See Q225 for the composition pattern in detail. See Q106 for traits. See Q109 for composition over inheritance.
Example
defines module qa.enums.swiftmigration defines type Colour Red Green Blue Shape Circle Rectangle Triangle defines trait <?- Shared contract for shapes with area calculation. This replaces Swift's enum with associated values. -?> Measurable area() as pure abstract <- rtn as Float? defines class CircleShape with trait of Measurable radius <- 0.0 CircleShape() -> radius as Float this.radius: radius override area() as pure <- rtn as Float: 3.14159 * radius * radius default operator RectangleShape with trait of Measurable width <- 0.0 height <- 0.0 RectangleShape() -> width as Float height as Float this.width: width this.height: height override area() as pure <- rtn as Float: width * height default operator defines function <?- Maps shape type to a description string. This replaces Swift's associated value extraction. -?> describeShape() as pure -> shapeType as Shape <- description as String: switch shapeType <- rtn as String: String() case Shape.Circle rtn: "A round shape" case Shape.Rectangle rtn: "A four-sided shape" case Shape.Triangle rtn: "A three-sided shape" default rtn: "Unknown shape" defines program SwiftEnumMigrationDemo() stdout <- Stdout() // === PATTERN 1: ENUM + DICT FOR SIMPLE DATA === hexCodes <- {Colour.Red: "#FF0000", Colour.Green: "#00FF00", Colour.Blue: "#0000FF"} for colour in Colour code <- hexCodes.getOrDefault(colour, "unknown") stdout.println(`${colour}: ${code}`) // === ENUM + FUNCTION FOR BEHAVIOUR === for shape in Shape stdout.println(describeShape(shape)) // === PATTERN 2: TRAIT HIERARCHY FOR COMPLEX VARIANTS === circle <- CircleShape(5.0) rect <- RectangleShape(4.0, 6.0) stdout.println(`Circle area: ${circle.area()}`) stdout.println(`Rectangle area: ${rect.area()}`)
Common mistakes
E50060 — String has no toUpperCase() method in EK9. Use upperCase() instead. See ek9 -h E50060 for details.
Incorrect:
stdout.println(describeShape(shape).toUpperCase())
Correct:
stdout.println(describeShape(shape))
E50060 — String has no toUpperCase() method in EK9. Use upperCase() instead. See ek9 -h E50060 for details.
Incorrect:
code <- hexCodes.getOrDefault(colour, "unknown").toUpperCase()
Correct:
code <- hexCodes.getOrDefault(colour, "unknown")
Other ways to ask this
- What is the EK9 equivalent of Swift enum with associated values?
- How do I model Swift's enum cases with data in EK9?
- How do I replace Swift associated values with EK9 composition?
Coming from another language?
Swift: enum cases carry associated values (case circle(radius: Double)), extracted via pattern matching (case .circle(let r)), powerful but couples data to identity. Rust: enum variants with fields, extracted via match arms. Java: enum constants with fields and constructors. Kotlin: sealed class with data class variants. EK9: enums are pure values, use Dict for simple data mapping and trait + class hierarchy for complex variant data, separation of concerns.
Keywords: swift, values, dict, associated, composition, data, variant, enum, pattern, enumeration, trait, migrate