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