Skip to content

Traits

Traits describe shared behavior that different types can implement.

They are useful when several types should support the same methods or associated values.

This trait requires a name method and also provides a default implementation of greeting.

trait Person {
const name : fn (&Self) -> str;
const greeting := fn (self : &Self) -> str => {
"Hello " & self.name();
};
};

To make a type support a trait, use impl TraitName for TypeName.

type User := struct { name : str };
impl Person for User {
const name := fn (self : &User) -> str => self.name;
};

Now any User value can use the trait’s behavior.

let user := User { name : "Ty" };
print(user.greeting());

Traits can also contain associated constants, not just methods.

trait Human {
const name : str;
const age := 10;
const country := "Zimbabwe";
};

Implementations may override the defaults.

type Ty := struct { };
type Tadiwa := struct { };
impl Human for Ty {
const name := "Ty";
};
impl Human for Tadiwa {
const name := "Tadiwa";
const age := 21;
const country := "US";
};

Trait-based code can work with dynamic trait values to help implement dynamic dispatch easily.

const show := fn (label : str, p : dyn:<Human>) => {
print(label & " -> name=" & p.name & ", age=" & p.age & ", country=" & p.country);
};