8.16.0.4

7.1 Combining Annotations🔗ℹ

The || annotation operator combines two annotations to produce a new one that is satisfied by values that satisfy either of the two annotations.

fun label(x :: Number || String):

  "figure " +& x

> label(1)

"figure 1"

> label("a")

"figure a"

> label(#false)

label: argument does not satisfy annotation

  argument: #false

  annotation: Number || String

A binding that uses an || annotation has only static information that is common to the two annotations. If is possible, for example, that two annotations both imply a third one.

class Posn(x, y):

  nonfinal

class Posn3D(z):

  extends Posn

class ColorPosn(hue, alpha):

  extends Posn

fun f(p :: Posn3D || ColorPosn):

  use_static

  p.x // both `Posn3D` and `ColorPosn` imply `Posn`

> f(Posn3D(1, 2, 3))

1

> f(ColorPosn(10, 20, "red", 1.0))

10

The && annotation operator combines two annotations to produce a new one that is satisfied by values that satisfy both of the two annotations.

fun label(x :: Indexable && Appendable):

  use_static

  if x[0]

  | x ++ x

  | x

> label("apple")

"appleapple"

> label([#false, 2, 3])

[#false, 2, 3]

As illustrated in this example, a binding that uses an && annotation has static information combined from the two annotations. If the two annotations provide differing static information, the left-hand annotation’s information is used. (If the static information from the two annotations is inherently in conflict, then presumably no value can satify both annotations at once.)