That could work. I would be concerned about something though: will binary zero always mean that it is safe to change branches? It is possible that a varient may be perfectly valid as zero, even when initialized. An example could explain better: type Variant = enum Point, NamedPoint Point2d = object case kind: Variant of Point: x, y: float of NamedPoint: name: string nx, ny: float
Just having the point at (0, 0) doesn't mean that the programmer intends for a Point to be reinterpreted as a NamedPoint. In fact, if you have, for example, some game entities, then those at the origin would have different assignment properties. I'm afraid that this could be surprising, if not dangerous. So, I like the idea, but I fear that it could create unexpected corner cases. I have an idea, and although it's a bit silly/simple, it could be advisable. Maybe we could urge developers to have a "nil case" that has no fields, especially in more critical code. That would place the burden on the programmer, but it's also very deliberate. The object could only be initialized into this state, and then the branch would be set in stone until `reset`: type Variant = enum None, Point, NamedPoint Point2d = object case kind: Variant of None: discard of Point: x, y: float of NamedPoint: name: string nx, ny: float var p = Point2d(kind: None) p.kind = Point p.x = 3.0 p.y = 2.0 echo p.x, ' ', p.y # Throws FieldError, as intended. p.kind = NamedPoint This seems like a workaround in some ways, though, and current code does not do this. It would be better if the language could enforce the variants without such a construction. I do understand the argument about flexibility. Nim developers are almost certainly going to assign to different fields, including the discriminant, after obtaining a `new`, zeroed object.