Type-oriented programming/Restricted properties

While subtyping is often ampliative, that is, a subtype contains all the properties of its supertype(s), it’s often useful to remove an inherited property from a subtype. For example, a complex has a real part and an imaginary part. Every real number is also a complex number but its imaginary part is always equal to zero so we don’t want this property to take up space in the instances. However we can’t remove the imaginary part altogether because it might be used by code working with complex numbers. What one can do is assign the property a fixed value:

type Complex {
  property real Float
  property imag Float

  func _add(x Complex) Complex {
    return new Complex {
      real=self.real+x.real,
      imag=self.imag+x.imag
    }
  }

  func _mul(x Complex) Complex {
    return new Complex {
      real=self.real*x.real-self.imag*x.imag,
      imag=self.real*x.imag+self.imag*x.real
    }
  }

  func description() String {
    return self.real.description() + "+" + self.imag.description() + "i"
  }
}

type Real : Complex {
  restrict imag Float = 0.0
}

main {
  var x = new Complex { real=2.0, imag=3.0 }
  var y = new Real { real=2.0 }
  return (x*y).description()
}

Note that the Real type now has only one stored property, but the methods in the Complex type can still be used with the subtype.

NB: The pseudocode can be tried out using the Funcy app, which can be downloaded for free from Apple’s App Store (iOS/macOS), Google Play (Android) or Amazon Appstore. The code to be executed must be placed in a main {} block.