Structures

Ad Astra supports a built-in syntax for creating structural data objects.

Informally, Ad Astra structures are key-value data objects that resemble JavaScript objects, Lua tables, or Rust BTreeMaps. They serve the purpose of object-oriented organization in script code design.

let my_object = struct {
    field_1: 100,

    field_2: 200,
    
    some_method: fn(a, b) {
        self.field_2 = self.field_1 * (a + b);
    },
};

my_object.some_method(3, 4);

my_object.field_2 == 700;

A structure object is constructed using the struct keyword followed by a definition body enclosed in {...} braces. The body consists of key-value entries separated by commas, with an optional trailing comma.

The key of an entry can be any valid Ad Astra identifier or an unsigned integer. The value of an entry can be any expression.

Structure values can be accessed using the field access operator: my_object.field_2.

Similar to script functions, structures are anonymous objects that are typically assigned to variables or passed directly to other expressions.

Fields Management

The script code can add new structure entries by assigning values to new object fields.

let my_object = struct {
    field_1: 10,
};

my_object.field_2 = 20;
my_object.field_3 = fn() {};

my_object.field_1? == true;
my_object.field_2? == true;
my_object.field_3? == true;
my_object.field_4? == false;

The existence of a structure entry can be tested using the ? nil-test operator on the structure field: foo.bar?.

Ad Astra does not provide a built-in way to remove entries from structures, but such a feature could be implemented via exported functions.

Structure Methods

A method of a structure is an entry where the value is a script function.

Inside the method implementation, you can use the built-in special self variable, which refers to the structure instance.

let my_object = struct {
    field: 10,
    method_1: fn() self.field * 3,
};

my_object.method_2 = fn() self.field * 4;

my_object.field = 100;

my_object.method_1() == 300;
my_object.method_2() == 400;