Structs
A struct is Falx's only user-defined compound type: a name, a list of fields (each with an optional default), and a set of methods.
struct Player {
health = 100;
name;
func takeDamage = define(amount) {
health -= amount; // fields are read/written directly, no `this.`/`self.`
}
func isAlive = define() {
return health > 0;
}
}
let p = Player();
p.name = "Hero";
p.takeDamage(30);
output(p.health); // 70
output(p.isAlive()); // true
output(typeof(p)); // "Player" -typeof() on an instance is the struct's own name
Fields & defaults
Declare a field with just a name (name;) or with a default value (health = 100;). Field declarations and method declarations can be interleaved in any order inside the struct body.
Constructing an instance
Calling the struct's name like a function creates an instance. Arguments are matched to fields positionally, in declaration order -there's no named-argument syntax and no way to skip a middle field while setting a later one.
null if it has none. A runtime error is only raised if you pass more arguments than the struct has fields; passing too few, even for fields with no default, is accepted silently.
struct Point {
x;
y;
label = "origin";
}
Point(); // x=null, y=null, label="origin" -no error
Point(1, 2); // x=1, y=2, label="origin"
Point(1, 2, "custom"); // x=1, y=2, label="custom"
Point(1, 2, "custom", "extra"); // runtime error: Expected 3 arguments, but got 4
Given this, it's worth treating "required" fields as a convention you enforce yourself (e.g. an assert() at the top of a method, or simply always passing every field) rather than something the language checks for you. That "too many arguments" case is E1021 in the errors reference; accessing or setting a field that was never declared is E1012/E1014.
Methods
A method is declared with func <name> = define(...) { ... } inside the struct body, exactly like a top-level function. Inside a method, every field of the struct is available directly by name -reading it reads the instance's value, and assigning to it (field = ... or field -= ...) mutates the instance. There is no this/self keyword.
Accessing fields and methods from outside
Use dot access, both to read and to assign:
let p = Player();
p.name = "Hero"; // set a field from outside
output(p.health); // read a field
p.takeDamage(10); // call a method
Accessing a field or method name that doesn't exist on the struct raises a runtime error rather than returning null.
Equality
Two struct instances are == if they're instances of the same struct definition and every field currently holds an equal value -value equality of the whole instance, not reference identity.
Structs across files
Structs are ordinary top-level declarations, so a struct defined in one .flx file is exported like anything else when another file requires it. See Modules and the structs-across-modules tutorial.