Type-oriented programming/Bounded type arguments

Consider the following code:

type Equatable { func equals(x Any) Bool }

type Complex : Equatable { property real Float property imag Float

func equals(x Any) Bool { if x is Complex then { var x = x as Complex return self.real == x.real & self.imag == x.imag }   return false } }

type Pair[T] { property first T property second T }

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

We now want to implement the  method also for  :

func equals(p Pair[T]) Bool { return self.first.equals(p.first) & self.second.equals(p.second) }

Note, however, that this code won’t compile since the compiler can’t be sure that  represents an equatable type. We need to change the declaration of  to

type Pair[T:Equatable] { ... }

Now it’s ensured that  is equatable and we can check pairs for equality:

main { var x = new Complex { real=2.0, imag=3.0 } var y = new Complex { real=2.0, imag=4.0 } var p1 = new Pair[Complex] { first=x, second=y } var p2 = new Pair[Complex] { first=x, second=y } return p1.equals(p2) }

Here, the  type argument is called bounded since there’s a type constraint placed on it.

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  block.