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.
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 referenceRules#
A type never flows as a value. There is no
Typetype to hold one in, notypeofoperator to produce one, novalue is Valueon a genericValue, and noClass.forNameto look one up by name.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 andstatic 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))fn describe<Value>(value: Value): String {
Value.show()
}
// error: `Value` has no member `show`Related#
- Why there is no reflection - why the four bridges above are the only ones, and what covers serialization and debug output instead.
- Methods and
static fns -Type.memberas a call and as a value. - Cases and match - matching a case without ever asking for a type.
- Encode and Decode - what covers serialization instead of reflection.
- Type parameters - where a name stands for a type instead of a value.