This is a case in which it would be desirable that some fields in object 
variants could share the name and hence, its value. In the following example, 
my first two attempts: Coordinates_1 and Coordinates_2, were typed intuitively, 
but failed to compile one after another due to the restrictions imposed to 
object variants.

The third attempt is the Coordinates object variant, and it works as designed, 
but lacks the flexibility for a more readable and intuitive definition, which 
ends up with additional names and cryptic implementation of the corresponding 
operators and procedures.

Please give me hope that there are plans or works to allow this possibility. In 
fact, the nicer and more readable one would be that of Coordinates_1.
    
    
    type
      
      # The 3 notations refer to the same 3-D entity, and some coordinates are 
shared
      CoordinateSystem = enum
        csCar, # Cartesian    (x,y,z)
        csCyl, # Cylindrical  (r,φ,z)
        csSph  # Spherical    (ρ,θ,φ)
      
      #[ Attempt 1: fails to compile due to redefinition of z and phi
      Coordinates_1 = object
        case cs: CoordinateSystem: # cs is the coordinate discriminator
          of csCar:
            x: float
            y: float
            z: float
          of csCyl:
            r: float
            phi: float
            z: float   # cy_z is the same as Cartesian z, but cannot duplicate 
labels
          of csSph:
            rho: float
            theta: float
            phi: float # sp_phi is the same as Cylindrical phi, but cannot 
duplicate labels
      ]#
      
      #[ Attempt 2: fails to compile due to duplication of labels
      Coordinates_2 = object
        case cs: CoordinateSystem: # cs is the coordinate discriminator
          of csCar:
            x: float
            y: float
          of csCar, csCyl:
            z: float  # both csCat and csCyl share z
          of csCyl:
            r: float
          of csCyl, csSph:
            phi: float # both csCyl and csSph share phi
          of csSph:
            rho: float
            theta: float
      ]#
      
      # this definition works but does not allow to share fields that represent 
the same entity
      Coordinates = object
        case cs: CoordinateSystem: # cs is the coordinate discriminator
          of csCar:
            x: float
            y: float
            z: float
          of csCyl:
            r: float
            phi: float
            cy_z: float   # the same as Cartesian z, but cannot share its name
          of csSph:
            rho: float
            theta: float
            sp_phi: float # the same as Cylindrical phi, but cannot share its 
name
    
    proc coordinates(coordSys: CoordinateSystem; arg0, arg1, arg2: float): 
Coordinates =
      case coordSys:
        of csCar: return Coordinates(cs: csCar, x:   arg0, y:     arg1, z:      
arg2)
        of csCyl: return Coordinates(cs: csCyl, r:   arg0, phi:   arg1, cy_z:   
arg2)
        of csSph: return Coordinates(cs: csSph, rho: arg0, theta: arg1, sp_phi: 
arg2)
    
    proc `$`(point: Coordinates): string =
      result = "("
      case point.cs:
        of csCar: result &= "x:" & $point.x   & ", y:" & $point.y     & ", z:" 
& $point.z
        of csCyl: result &= "r:" & $point.r   & ", φ:" & $point.phi   & ", z:" 
& $point.cy_z
        of csSph: result &= "ρ:" & $point.rho & ", θ:" & $point.theta & ", φ:" 
& $point.sp_phi
      result &= ")"
    
    echo coordinates(csCar, 1, 2, 3) #output: (x:1.0, y:2.0, z:3.0)
    echo coordinates(csCyl, 4, 5, 6) #output: (r:4.0, φ:5.0, z:6.0)
    echo coordinates(csSph, 7, 8, 9) #output: (ρ:7.0, θ:8.0, φ:9.0)
    
    
    
    Run

Reply via email to