Advanced Features

Nebula includes powerful features for building complex applications.

Structs

Define custom data structures with named fields:

struct User {
    name: wrd,
    age: int,
    active: bool,
}

perm user = User {
    name: "Alex",
    age: 25,
    active: on
}

log(user.name)    # Alex
log(user.age)     # 25
log(user.active)  # on

Nested Structs

struct Address {
    city: wrd,
    country: wrd,
}

struct Profile {
    name: wrd,
    address: Address,
}

perm profile = Profile {
    name: "Alice",
    address: Address {
        city: "Toronto",
        country: "Canada"
    }
}

log(profile.address.city)  # Toronto

Error Handling

Use try-catch-finally for runtime error handling:

try do
    perm result = risky_operation()
    log("Success:", result)
catch err do
    log("Error occurred:", err)
finally do
    log("Cleanup complete")
end

Assert

Verify conditions at runtime:

fn divide(a, b) do
    assert b != 0
    give a / b
end

Async & Concurrency

Note: Async features are experimental.

Async Functions

Mark functions as async and use await:

async fn fetch_data(url) do
    # Simulated async operation
    give "data from " + url
end

async fn main() do
    perm result = await fetch_data("https://api.example.com")
    log(result)
end

Spawn

Run tasks concurrently:

spawn log("Running in background")
log("Running in foreground")

Channels

Communicate between concurrent tasks:

perm ch = chan()

spawn do
    ch <- "Hello from task"
end

perm msg = <- ch
log(msg)  # Hello from task

Modules

Organize code into reusable modules:

# math.na
export fn square(x) = x * x
export fn cube(x) = x * x * x

# main.na
use math

log(math.square(5))  # 25
log(math.cube(3))    # 27

Selective Imports

use math { square, cube }

log(square(4))  # 16

Enums

Define enumerated types:

enum Status {
    Pending,
    Active,
    Completed,
    Cancelled,
}

perm current = Status.Active

match current do
    Status.Pending => log("Waiting..."),
    Status.Active => log("In progress"),
    Status.Completed => log("Done!"),
    Status.Cancelled => log("Cancelled"),
end

Type Aliases

Create readable type names:

type UserId = int
type UserName = wrd
type UserList = lst

perm id: UserId = 12345
perm name: UserName = "alice"

Traits (Interfaces)

Planned Feature

Define shared behavior:

trait Printable {
    fn to_string() -> wrd
}

impl Printable for User {
    fn to_string() do
        give "User: " + self.name
    end
}