Use the structure keyword to define data shapes. Fields can have optional types and default initialization expressions.
structure Person {
String name;
int age = 0;
function void greet() {
print("Hello, my name is " + this.name);
}
}
p = Person("Alice", 30);
p.greet(); # Prints: Hello, my name is Alice
You can define an initialization method named constructor.
structure User {
name;
role;
function constructor(name, role) {
this.name = name;
this.role = role;
}
}
u = User("Bob", "Admin");
Structures can inherit fields and methods using extends.
structure Animal {
name;
function speak() { print("Generic noise"); }
}
structure Dog extends Animal {
breed;
function speak() { print("Woof!"); }
}
d = Dog("Buddy", "Golden Retriever");
d.speak(); # Prints: Woof!
You can pass expressions to the parent in the extends clause, evaluated using the child's field arguments.
structure Shape { area; }
# Square passes (width * width) as the value for Shape's 'area' field
structure Square extends Shape(width * width) {
width;
}
s = Square(5);
print(s.area); # 25
Use super(...) inside a child constructor to call the parent structure's constructor.
structure User {
name; role;
function constructor(name, role) {
this.name = name;
this.role = role;
}
}
structure Admin extends User {
level;
function constructor(name) {
super(name, "Admin"); # Call parent constructor
this.level = 1;
}
}
a = Admin("Alice");
print(a.role); # Admin
print(a.level); # 1
Use private and protected modifiers on fields and methods within structures.
private: Access restricted to the defining structure only.protected: Access restricted to the defining structure and its subclasses.
structure BankAccount {
private double balance = 0.0;
function void deposit(double amount) { this.balance += amount; }
function double getBalance() { return this.balance; }
}
acc = BankAccount();
acc.deposit(100.5);
print(acc.getBalance()); # 100.5
# acc.balance = 999; # Error: access denied
Structures can be declared as threaded to run on their own background thread. This makes them Active Objects: all method calls and field access/assignments are executed sequentially on a dedicated thread, ensuring thread safety.
threaded structure Counter {
int count = 0;
function void increment() {
this.count = this.count + 1;
}
}
c = Counter(); # Runs on its own thread
c.increment(); # Executed asynchronously on c's thread
Triggers are reactive blocks inside a structure that fire automatically when a field is assigned. They are useful for reactive programming and UI updates.
| Form | Description |
|---|---|
on (boolExpr) { ... } | Fires after any field write if boolExpr is truthy. |
on (field changed) { ... } | Fires only if the value of field actually changed. |
structure Tracker {
any state;
int changeCount = 0;
# Fires whenever 'state' value actually changes
on (state changed) {
this.changeCount += 1;
print("State changed to: " + this.state);
}
# Fires if changeCount exceeds 10
on (changeCount > 10) {
print("Threshold reached!");
}
}
Use the static keyword for fields and methods belonging to the structure type rather than instances.
structure MathUtils {
static double PI = 3.14159;
static function double circleArea(double r) {
return MathUtils.PI * r * r;
}
}
area = MathUtils.circleArea(5);
Methods can be added to structures or instances at runtime using addMethod.
structure User { String name; }
function String sayHello() { return "Hello, " + this.name; }
# Add to structure type (affects all new instances)
User.addMethod("hello", sayHello);
# Add to a specific instance only
u = User("Alice");
function String farewell() { return "Goodbye from " + this.name; }
u.addMethod("bye", farewell);
print(u.hello()); # Hello, Alice
print(u.bye()); # Goodbye from Alice