Structs Arrive in Luma - Phase 1 is Here Elegance

Structs Arrive in Luma - Phase 1 is Here Elegance

November 23, 2025·
Luma Core Team

Luma continues to evolve, and today we’re excited to introduce one of the most requested language features: structs.

This is the foundation for building richer data models, larger programs, and ultimately unlocking higher-level abstractions such as methods, impl blocks, and traits.

Structs are now fully supported in Luma as plain data containers, and they already integrate cleanly with the rest of the language: lists, maps, functions, optionals, and composite data structures.

This post explains:

  • What’s implemented today
  • What works with structs
  • What does not work yet
  • What’s coming next in the roadmap

Let’s dive in.

Structs: Phase 1 - What’s Available Today

Phase 1 focuses on data-only structs, with positional construction and field access.

Declaring a struct

struct Person {
    name: str
    age: int
}

This compiles to a Go type:

type Person struct {
    name string
    age  int
}

Constructing a struct (positional)

alice: Person = Person("Alice", 25)

Luma compiles this to a Go composite literal:

var alice Person = Person{"Alice", 25}

Accessing fields

print(alice.name)
print(alice.age)

Structs in Functions

fn birthday(p: Person) -> Person {
    return Person(p.name, p.age + 1)
}

alice: Person = Person("Alice", 25)
older: Person = birthday(alice)
print(older.age)

Structs in Lists

Yes - lists of structs work exactly as expected:

people: [Person] = [
    Person("Alice", 25),
    Person("Bob", 30),
]

print(people[0].name)

Structs in Maps

people_by_name: {str: Person} = {
    "Alice": Person("Alice", 25),
    "Bob": Person("Bob", 30),
}

print(people_by_name["Alice"].age)

Nested Structs

struct Address {
    city: str
}

struct Person {
    name: str
    age: int
    address: Address
}

alice: Person = Person("Alice", 25, Address("Tallinn"))
print(alice.address.city)

Optional Structs (?Person)

You can store structs inside optional types:

best_friend: ?Person = Person("Alice", 25)
no_friend: ?Person = nil

Compilation lowers this cleanly to pointer types (*Person).

Field access still requires a non-optional:
(We’ll add smarter auto-deref rules in the future.)

Not Implemented Yet (By Design)

The following features are explicitly out of scope for Phase 1 and coming later:

Named struct literals

This will NOT work yet:

Person {
    name: "Alice",
    age: 25
}

Positional construction is currently required.

Field mutation

alice.age = 30   // not supported yet

Methods / impl blocks

impl Person {
    fn greet() -> str { ... }
}

Coming soon in Phase 2.

Traits + trait implementations

trait Greeter { ... }
impl Greeter for Person { ... }

Phase 3.

Struct Roadmap - What’s Coming Next

Now that structs work cleanly across the whole compiler pipeline, here’s what’s next.

Phase 1.5 - Named Struct Literals

Add support for:

Person { name: "Alice", age: 25 }

This requires a new AST node and disambiguation from {map: literals}.

Phase 2 - impl Blocks + Methods

Enable struct-associated functions:

impl Person {
    fn greet(self) -> str {
        return "Hello, ${self.name}!"
    }
}

Methods will lower to Go methods or helper functions.

Phase 3 - Traits + Interfaces

trait Greetable {
    fn greet() -> str
}

impl Greetable for Person {
    fn greet() -> str { ... }
}

fn sayHello(x: Greetable) { ... }

Traits will map directly to Go interfaces.

Phase 4 - Named Field Mutation

alice.age = 30

This requires type-safe mutation and updated codegen.

Phase 5 - Named Struct Update Syntax

Possibly:

alice2 = Person { ...alice, age: alice.age + 1 }

(Likely a later convenience feature.)

Phase 6 - Struct Generics

This unlocks expressive, reusable types:

struct Box[T] {
    value: T
}

Summary

Structs are now a first-class citizen in Luma:

  • Struct declaration
  • Positional construction
  • Field access
  • Lists, maps, nested structs
  • Functions and return types
  • Optional structs
  • Clean Go codegen and stable semantics

You can already build real data models in Luma today - and this foundation sets the stage for methods, traits, and beyond.

If you’re building with Luma or experimenting with the new struct system, share your examples and ideas - we’re just getting started.

Last updated on