lloyAlloy on GitHub
Traits
Docs

Traits

Updated
struct Vec2
    x: number
    y: number
end

impl Display for Vec2
    function to_string(self): string
        return `({self.x}, {self.y})`
    end
end

The trait shapes the std exports, for a bound and for impl X for Struct. Each is a table type of the methods it asks for; a struct that has them passes.

An impl may also name Lt, Le, Call, Len, Concat, and Drop, which write __lt, __le, __call, __len, __concat, and Destroy. A trait the file declares with one of these names wins over the std's.

Fields

Display

Display = { to_string(self): string }

How a value prints. An impl Display writes to_string and the emit sets __tostring, so print(v) and an interpolation use it.

function show<T: Display>(v: T): string
    return v:to_string()
end

Debug

Debug = { debug(self): string }

The developer view of a value, what @derive(Debug) writes and $dbg prints.

function trace<T: Debug>(v: T): string
    return v:debug()
end

Clone

Clone<T> = { clone(self): T }

A copy of a value, what @derive(Clone) writes.

function twice<T: Clone>(v: T)
    return v:clone()
end

Eq

Eq = { eq(self, other): boolean }

Equality. An impl Eq sets __eq, so a == b runs it.

function same<T: Eq>(a: T, b: T): boolean
    return a:eq(b)
end

PartialEq

PartialEq = { eq(self, other): boolean }

The same shape as Eq, under the name Rust uses for equality that is not total.

function same<T: PartialEq>(a: T, b: T): boolean
    return a:eq(b)
end

Ord

Ord = { lt(self, other): boolean, le(self, other): boolean }

Ordering. An impl Ord sets __lt and __le, so a < b runs it, and @derive(Ord) writes both.

function smallest<T: Ord>(a: T, b: T): T
    return a:lt(b) ? a : b
end

Add

Add<T> = { add(self, other): T }

Addition. An impl Add sets __add, so a + b runs it.

function sum<T: Add>(a: T, b: T)
    return a:add(b)
end

Sub

Sub<T> = { sub(self, other): T }

Subtraction, through __sub.

function diff<T: Sub>(a: T, b: T)
    return a:sub(b)
end

Mul

Mul<T> = { mul(self, other): T }

Multiplication, through __mul.

function scale<T: Mul>(a: T, b: T)
    return a:mul(b)
end

Div

Div<T> = { div(self, other): T }

Division, through __div.

function ratio<T: Div>(a: T, b: T)
    return a:div(b)
end

Serialize

Serialize = { serialize(self): any }

A value as plain data. The bound asks for serialize, which @derive(Serialize) writes beside to_table and from_table, so a derived struct meets the bound.

import { Serialize } from "@alloy/std/serde"

function to_data<T: Serialize>(v: T): any
    return v:serialize()
end