Skip to content

Objects

cyxigo edited this page Jul 26, 2026 · 8 revisions

Introduction

Wi is an object-oriented programming language. But unlike languages like Java or C#, Wi uses concatenative prototype-based OOP.

Instead of classes, Wi has objects. You create an object, and then you can clone it to make new objects. You can also add new fields to objects, extending them with more functionality.

Object definition

Objects, just like functions, are expressions. So to define an object you need to declare a variable and define it with the object expression:

var o = object {
};

Objects are just bags of data. How do you define that data? You define fields:

var o = object {
    x = 0;
};

Now object o has a field called x with the value 0. To access that field, we use the field operator .:

var o = object {
    x = 0;
};

o.x = 1;
print(o.x); // 1

Methods

A method is a function associated with a specific object. To create a method, we simply define a function field:

var o = object {
    my_method = function(self) {
    };
};

You may notice the parameter self - this is the object reference parameter. It's here so we can actually access the object's fields within its method.

Now, remember the invocation operator -> we talked about earlier? That's why it exists. If you access a method via the field operator . you need to pass self explicitly, but -> passes self implicitly!

o.my_method(o); // bad (explicit self)
o->my_method(); // good (implicit self)

It's not only easier to write ->, it's also faster in execution.

Cloning

We talked about how Wi relies on cloning, and we talked about the new operator earlier. Now it all comes together. But in case you forgot:

The new operator is used to clone an object. It creates a new object that is a copy of the original.

Here's an example:

var obj_person = object {
    name = "";
};

var alice = new obj_person;
alice.name = "Alice";

var bob = new obj_person;
bob.name = "Bob";

print(alice.name); // Alice
print(bob.name);   // Bob

You may notice the obj_ prefix here. Wi has a convention that every object intended to be used as a template should start with obj_, to avoid confusion between the template and its clones.

But writing:

var bob = new obj_person;
bob.name = "Bob";

Can become very much of a hustle if you got more than one field, that's why Wi supports this useful syntax:

var bob = new obj_person {
    name = "Bob";
};

You can even add new fields there:

var bob = new obj_person {
    name = "Bob";
    job = "unemployed";
};

And of course, cloning works with methods too:

var obj_person = object {
    name = "";
    greet = function(self) {
        print("Hello " .. self.name .. "!");
    }; 
};

var alice = new obj_person {
    name = "Alice";
};

alice->greet(); // Hello Alice!

var bob = new obj_person {
    name = "Bob";
};

bob->greet(); // Hello Bob!

Does that look familiar? Yeah, it's the example from the Wi repository README.md!

Next: Error Handling

Clone this wiki locally