Experimental Features

These features work in Luwu today, but their design isn't final yet and their syntax may change.

Prefer the stable features on the other pages for code you'll keep.

Your editor reports them as disabled until you turn on their debug flags.

Push and pop operators

<+ adds values to a container and <- takes the last value back out.

They're a standard way to add to and take from any container. They work the way # works on anything that defines __len.

On a plain array, they add to and remove from the end:

local queue = {}
queue <+ "first"
queue <+ "second", "third"
print(#queue)

const last = <-queue
print(last, #queue)

Nil values are skipped and never leave a hole in the array.

A class defines __push and __pop to decide how those operators work on its objects.

This inventory holds at most two items. Code that fills it doesn't need to know that:

class Inventory(capacity: number)
    items: { string } = {}

    function __push(self, ...: string)
        for _, item in { ... } do
            if #self.items < self.capacity then
                table.insert(self.items, item)
            end
        end
    end
    function __pop(self): string?
        return table.remove(self.items)
    end
    function __len(self): number
        return #self.items
    end
end

const list = {}
list <+ "sword", "shield", "potion"

const bag = Inventory(2)
bag <+ "sword", "shield", "potion"

print(#list, #bag)
print(<-list, <-bag)

The pop syntax isn't decided yet and may change.

match expressions

A match expression picks a value based on what another value looks like.

Each case is checked in order and the else arm is required.

const function describe(count: number): string
    return match count
        case 0 then "none"
        case 1 | 2 | 3 then "a few"
        else "many"
end

print(describe(0), describe(2), describe(50))

Matching objects

case is Class matches objects of a class. Add a pattern to pull out their fields.

A case can add when conditions, like if local.

class Circle(radius: number) end
class Rect(width: number, height: number) end

const function describe(shape: Circle | Rect): string
    return match shape
        case is Circle.{ radius } then `circle with radius {radius}`
        case is Rect.{ width, height } when width == height then `square of {width}`
        case is Rect.{ width, height } then `{width} by {height} rectangle`
        else "unknown shape"
end

print(describe(Circle(2)), describe(Rect(3, 3)), describe(Rect(2, 5)))