State, and self
An archetype's methods work on the instance that calls them — self is that one.
An archetype does not only carry fields: it carries methods, and each works on the instance that calls it.
archetype Character {
name: str;
energy: int;
greet() {
Console.print(text: $"I am {self.name}, energy {self.energy}.");
}
tire(cost: int) {
self.energy := self.energy - cost;
}
}
@entry(start)
object MyProgram {
start() {
var simon := Character(name: "Simon Magus", energy: 10);
var helen := Character(name: "Helen", energy: 7);
simon.tire(cost: 3);
simon.greet();
helen.greet();
}
}
self names this very instance
Since 1.2.1, self was a formula you copied along. Here it takes its full meaning:
greet() {
Console.print(text: $"I am {self.name}, energy {self.energy}.");
}
When simon.greet() runs, self is Simon; when helen.greet() runs, self is Helen. One
method, written once, and every instance passes through it with its own values. In an
object, self named the unique instance; in an archetype, it names the one calling.
State changes, and it stays
tire(cost: int) {
self.energy := self.energy - cost;
}
simon.tire(cost: 3) takes 3 from Simon’s energy — and his alone: the example prints 7
for Simon and 7 for Helen, each by its own path. The change outlives the call: the instance
carries its state, the methods make it live.
Fields can also be changed from outside — simon.energy := 3; is allowed. Going through a
method is not a rule of the language, it is a discipline: tire says why the energy drops,
where the bare assignment says nothing.
Two names do not make two instances
var alias := simon;
alias.tire(cost: 3);
After that, simon.energy dropped too — alias and simon name the same instance.
Copying a variable does not copy the character: there is still one Simon, reached by two
names. It is the same truth as the previous subsection’s =, seen from the other side:
identity belongs to the instance, not to the name.
Your turn
- Tire Helen by 2 and check that Simon did not move.
- Add a
rest(gain: int)method that gives energy back, and let Simon rest. - Write
var alias := simon; alias.tire(cost: 5);then makesimongreet: his energy dropped. Two names, one character. - Make a character greet whose energy fell to zero — nothing forbids it yet. The next subsection gives the constructor the power to impose rules at birth; section 8 will give methods the power to refuse.