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