There is no reflection

A type never flows as a value, so there is no Type type, no typeof and no Class.forName - only four syntactic bridges connect a type to a value, all resolved at compile time.

Diese Seite gibt es noch nicht auf Deutsch, deshalb steht sie hier auf Englisch. Zur englischen Seite

Types and values are two worlds that meet in exactly four places, and every one of them is ordinary syntax the checker resolves before a program runs - never a value a program can hold, inspect or branch on at runtime.

Example#

type Shape {
  case Circle(radius: Int)
  case Square(side: Int)

  static unit = Shape.Circle 1

  fn area(): Int {
    match self {
      .Circle(radius) => radius * radius
      .Square(side) => side * side
    }
  }
}

const shapes = [Shape.Circle(2), Shape.Square(3), Shape.unit]
print shapes.map({ _.area() }).toList()

Syntax#

Point(1, 2)          the constructor
Point.origin          a static member
Point.tryFrom(text)     a static member
Shape.Circle          a case
Point.area            a method reference

Rules#

  1. A type never flows as a value. There is no Type type to hold one in, no typeof operator to produce one, no value is Value on a generic Value, and no Class.forName to look one up by name.

  2. Exactly four syntactic forms bridge a type and a value, and all four are resolved at compile time. A constructor call (Point(1, 2)), a static member (Point.origin, Point.tryFrom(text)), a case (Shape.Circle), and a method reference (Point.area, the unbound function value - see Methods and static fns). None of them look a name up while the program runs.

What this is not#

Matching on a case is not reflection. match self { .Circle(radius) => ... } reads data that is already there; it never asks what type self is at runtime, and the compiler already knows the exhaustive list.

type Shape {
  case Circle(radius: Int)
  case Square(side: Int)
}

fn isRound(shape: Shape): Bool {
  match shape {
    .Circle(_) => true
    .Square(_) => false
  }
}

print isRound(Shape.Circle(1))
Kompiliert nicht
fn describe<Value>(value: Value): String {
  Value.show()
}
// error: `Value` has no member `show`
Esc