Skip to content

Classes

A class instance is shared on assignment and can be changed through any name that refers to it; see Values & Sharing. A class with a query(cycle) method is a script pattern.

class Point {
let x; // field
let y: Number; // field with an advisory annotation
fn new(x, y = 0) { // constructor
this.x = x;
this.y = y;
}
fn add(other) -> Point { // method
return Point(this.x + other.x, this.y + other.y);
}
fn __str__() { // how print() and f-strings show it
return f"({this.x}, {this.y})";
}
}
let p = Point(3, 4); // call the class to construct
let q = p.add(Point(y: 2, x: 1)); // named arguments work
assert q.x == 4;
print(q); // (4, 6)
MemberSyntaxNotes
Fieldlet name; or let name: Type;Declared once; takes no /// documentation
Constructorfn new(params) { … }Called by ClassName(args); sets fields through this
Methodfn name(params) { … }Called as instance.name(args); /// documents it
Displayfn __str__() { … }Used by print() and format strings

Parameters of new and methods follow the function rules: defaults, named arguments, rest parameters, and argument-count errors. A method’s default may use this.

A field and a method may share a name: p.x reads the field and p.x() calls the method.

Fields are read and assigned from anywhere, including through nested instances, and take compound assignment:

class Inner {
let value;
fn new(v) { this.value = v; }
}
class Outer {
let inner;
fn new(i) { this.inner = i; }
}
let o = Outer(Inner(1));
o.inner.value = 5;
o.inner.value += 1;
assert o.inner.value == 6;
print(o.inner.value);

A method that assigns to this changes the instance in place, and every name sharing the instance sees the change. .clone() makes an independent copy.

With __str__, print() and f"{…}" show what it returns. Without it, or when it returns a non-String, an instance shows as its class name and its fields in alphabetical order:

class Pair {
let b;
let a;
fn new(a, b) { this.a = a; this.b = b; }
}
print(Pair(1, 2)); // Pair { a: 1, b: 2 }
assert type(Pair(1, 2)) == "Pair";

A class in a module is exported like a fn and constructed as module.ClassName(args). private class keeps it inside the module. See Modules.

  • Inheritance — no extends or super.
  • Static methods or fields — every member belongs to an instance.
  • Private members — every field and method is public. For encapsulation, use module-level private.
  • Getters and setters — fields are read and assigned directly.