Classes & objects

Since beta-2.0.0 you can define your own types. A class groups fields (data) and methods (functions that work on that data). Inside a method, self is the object the method was called on.

ton.class Point {
    ton.function init(x, y) {
        self.x = x
        self.y = y
    }
    ton.function distanceTo(other) {
        return sqrt((self.x - other.x) ** 2 + (self.y - other.y) ** 2)
    }
    ton.function toString() {
        return f"({self.x}, {self.y})"
    }
}

ton.Point a = Point(0, 0)
ton.let b = Point(3, 4)
print(a.distanceTo(b))     // 5
print(b)                   // (3, 4) — print/str/f-strings use toString()
b.x = 10                   // fields can be read and written with the dot
  • Creating an object: call the class like a function. Its init method (the constructor) receives the arguments; without init, the class takes no arguments.
  • Field declarations in the class body (ton.int count = 0, ton.let items = []) give every new object its own initial value, before init runs. Fields can also be created at any time by assigning self.name = ....
  • Typed variables: ton.Point p = ... checks that the value is a Point (or a subclass of it), or nil.
  • toString(), if defined, is used whenever the object is turned into text. Without it, an object prints as Point{x: 3, y: 4}; json(obj) gives {"x":3,"y":4}.
  • Methods are values: ton.let f = point.toString keeps self bound, so f() works later.
  • Objects are passed by reference (like arrays and dicts): == is true only for the very same object. copy(obj) / deepcopy(obj) duplicate one.

Inheritance — extends makes a class reuse (and override) everything from a parent class; super.method(...) calls the parent's version:

ton.class Animal {
    ton.string sound = "..."
    ton.function init(name) { self.name = name }
    ton.function speak() { return f"{self.name} says {self.sound}" }
}

ton.class Dog extends Animal {
    ton.int tricks = 0
    ton.function init(name) {
        super.init(name)
        self.sound = "woof"
    }
    ton.function learn() {
        self.tricks++
        return self              // returning self allows chaining
    }
}

ton.Dog rex = Dog("Rex")
print(rex.speak())                     // Rex says woof
print(rex.learn().learn().tricks)      // 2
print(isinstance(rex, Animal))         // true
print(type(rex))                       // Dog

Objects work with the rest of the language: "x" in point tests a field, keys(obj)/values(obj)/items(obj) list fields, ton.let {x, y} = point destructures one, {...point} copies its fields into a dict, and throw MyError("...") throws one (the catch receives the object itself).

Edit this page on GitHub