leviathan-lang.com / docs / learn
Classes and objects
Members, constructors, labeled constructors, operators, and get/set properties.
A class is a set of members
Now the payoff of the "one rule." A class is a set of members, and a member is just a typed slot bound to a label. Some slots hold data; some hold something callable (a method). Constructors, operators, and properties are all members too: marked, not special-cased.
A class with constructors, a method, and operators
class Counter {
public string label;
public int value = 0;
// A constructor is a member marked by 'new'. The name is only a label.
new Counter(string startLabel) {
label = startLabel;
}
// A second constructor, selected by its label rather than the class name.
new WithValue(string startLabel, int start) {
label = startLabel;
value = start;
}
// A method. Arrow body: '=>' IS the return.
string describe() => "${label} = ${value}";
// An operator is a method whose name is a symbol.
Counter (+)(int n) => Counter::WithValue(label, value + n);
bool (==)(int n) => value == n; // (!=) derives automatically as !(==)
}
Constructing objects
Constructing takes no new at the call site. You name the type, or a labeled constructor:
Constructing and using a Counter
class Counter {
public string label;
public int value = 0;
new Counter(string startLabel) {
label = startLabel;
}
new WithValue(string startLabel, int start) {
label = startLabel;
value = start;
}
string describe() => "${label} = ${value}";
Counter (+)(int n) => Counter::WithValue(label, value + n);
bool (==)(int n) => value == n; // (!=) derives automatically as !(==)
}
Counter c = Counter("hits"); // -> label "hits", value 0
Counter d = Counter::WithValue("x", 3); // labeled constructor
Counter e = c + 5; // the (+) operator: value becomes 5
bool hit = e == 5; // the (==) operator: true
console.writeln(c.describe());
console.writeln(d.describe());
console.writeln(hit);
console.writeln(e.describe());
console.writeln(e != 4); // (!=) came for free
hits = 0
x = 3
true
hits = 5
true
Properties
Properties are typed views over a slot, declared with get and set. Objects are references
(shared on assignment and passing); primitives and arrays are values.
A computed read/write property
class Thermostat {
int celsius = 20;
get fahrenheit() => celsius * 9 / 5 + 32; // computed, read-only
set fahrenheit(int f) celsius = (f - 32) * 5 / 9;
}
Thermostat t = Thermostat();
console.writeln(t.fahrenheit);
t.fahrenheit = 212;
console.writeln(t.celsius);
console.writeln(t.fahrenheit);
68
100
212
A field whose value is fixed once at construction is readonly; a compile-time constant field is
const; a back-reference that shouldn't keep its target alive is weak. The reference entries on
readonly fields, const, and weak fields have the details.
See also
- readonly fields — Fix an instance field once, either in its initializer or in every constructor, and keep it read-only afterwards.
- const declarations — Fix a local, field, global, parameter or loop binding after its initializer, with the exact rules for each kind of slot.
- weak fields — Hold a non-owning reference to an object that reads as None once the object is gone.