githubEdit

Functions

Stof functions.

In Stof, functions are first-class data. You can:

  • Store them in variables

  • Pass them around as values

  • Send them over APIs

  • Execute them anywhere

circle-info

Note: functions and field data in practice should often come from different places, only mixed at runtime in Stof for manipulation & usage (most export formats only consider fields anyways).

In reality, it is tricky to heavily mix both functions and fields in documents that are stored as versions/behavior inevitably changes (classic separation of concerns issues).

One strategy to combat this, however, is to put APIs in a separate root object (or known location). In this case, it's as easy to replace as swapping a file in a file system, without worry of missing data.

Keep in mind that this ability is very useful despite the potential learning curve - especially when sending API + data over the wire for another system to use in its own sandbox of Stof.

circle-info

Second Note: prototypes are a thing in Stof and are extremely useful if you need to avoid mixing both fields and functions within the same objects. You can import/create raw data, then cast the object to the prototype of your choice for a complete API with schemas, validations, types, etc.

Coffee: {
    const bool decaf: false // never!!
    bool light_roast: false
    
    Customer: {
        name: "Stanly Yelnatz III"
        time: Time.now()
    }
    
    Shop: {
        str name: "Coffee Pot"
        str address: "42 Wallaby Way, Sydney"
        
        fn order() -> str {
            const order = `${self.name} on ${self.address}\n`;
            order.push(`1 ${super.light_roast ? 'light' : 'dark'} roast Coffee`);
            order
        }
    }
    
    fn customer_name() -> str {
        self.Customer.name
    }
}

#[main]
fn main() -> void {
    pln(self.Coffee.customer_name());
    pln(self.Coffee.Shop.order());
}

Async

The Stof runtime supports async processes at its core. Functions can be async with an #[async] attribute (or the async syntax that adds this attribute).

Flexible Async

Because async is so foundational in Stof, any function, even ones not marked as async can be called asynchronously.

Attributes

Just like fields, functions can have custom attributes.

Arrow Functions

As a Field

There are times when functions (or function pointers "fn") end up as a field. You can call them just like normal functions!

Return

A return statement is one without a semi-colon, returning the last value on the stack. Or, an explicit "return" statement within the function.

Static Functions

Stof doesn't have a static concept like other languages, but it does have prototypes. And because prototypes have a type name, you can call functions directly on that prototype using the name instead of the object, mimicking behavior that would seem like a "static" function in another language.

circle-info

The syntax looks like it does because the type name is filling in the path portion of the function call. Take a look at Prototypes for more information.

This is important to keep in mind, though, because when calling a function like this, "self" will be the prototype object (like a normal function call), and even though this makes sense, you may not expect it.

circle-check

Last updated