My view is that in general people shouldn't use "raw" object variants in 
important code. They should either stick to some guidelines for using them 
(this is not a rare thing in code) or wrap around those guidelines with macros.

As an example of a guideline: each branch must have a single field, and there 
should be no fields outside of the variant fields.
    
    
    type
      ABCKind = enum a, b, c
      AB = object
        x, y: int
      C = object
        z: string
      ABC = object
        case kind: ABCKind
        of a, b:
          ab: AB
        of c:
          c: C
      Foo = object
        name: string
        abc: ABC
    
    # AB and C have automatically defined ==
    
    # we can easily define == for ABC, we could even do this for generic object 
variants of this form if the type system allowed it:
    proc `==`(u, v: ABC): bool =
      if u.kind != v.kind: return false
      result = case u.kind
      of a, b: u.ab == v.ab
      of c: u.c == v.c
    
    # == for Foo is now defined as well
    
    
    Run

It's more verbose but is it really any harder to work with than ADTs or OOP? 
How do you even define == for ADTs in user code?

Reply via email to