BRAIDGROUP
RESEARCH & DEV
40. Documentation

Tutorials

1. Your First Braid Program

Create a file hello.br:

fn main() {
    print("Hello, Braid!");
}

Run it:

braidc run hello.br

Now let's add variables:

fn main() {
    let name = "World";
    let count = 42;
    let pi = 3.14159;
    print("Hello, " + name + "!");
    print("The answer is " + count);
    print("Pi is " + pi);
}

Notice that Braid infers types (string, int, float). All statements end with semicolons.

2. Building a Calculator

Create a file calculator.br. First, define functions for basic operations:

fn add(a: float, b: float) -> float {
    return a + b;
}

fn subtract(a: float, b: float) -> float {
    return a - b;
}

fn multiply(a: float, b: float) -> float {
    return a * b;
}

fn divide(a: float, b: float) {
    if b == 0.0 {
        print("Error: division by zero");
        return nil;
    }
    return a / b;
}

Now add control flow to parse an operation:

fn calculate(op: string, x: float, y: float) {
    match op {
        "+" => return add(x, y),
        "-" => return subtract(x, y),
        "*" => return multiply(x, y),
        "/" => return divide(x, y),
        _ => {
            print("Unknown operator: " + op);
            return nil;
        }
    }
}

fn main() {
    let result = calculate("+", 10.0, 5.0);
    if result != nil {
        print("10 + 5 = " + result);
    }

    // Use a while loop to run multiple calculations
    let i = 0;
    while i < 3 {
        let r = calculate("*", i, i + 1);
        print(i + " * " + (i + 1) + " = " + r);
        i = i + 1;
    }
}

3. Creating a Data Structure

Define a struct with associated methods:

struct Rectangle {
    width: float;
    height: float;
}

// Methods are standalone functions that take a struct
fn area(self: Rectangle) -> float {
    return self.width * self.height;
}

fn perimeter(self: Rectangle) -> float {
    return 2.0 * (self.width + self.height);
}

fn scale(self: Rectangle, factor: float) -> Rectangle {
    return Rectangle {
        width: self.width * factor,
        height: self.height * factor,
    };
}

fn main() {
    let rect = Rectangle {
        width: 5.0,
        height: 3.0,
    };
    print("Area: " + area(rect));         // 15.0
    print("Perimeter: " + perimeter(rect)); // 16.0

    let big = scale(rect, 2.0);
    print("Scaled area: " + area(big));   // 60.0
}

Structs can be nested and stored in arrays. Use . for field access and assignment:

struct Circle {
    center: Point;
    radius: float;
}

struct Point {
    x: float;
    y: float;
}

fn main() {
    let circle = Circle {
        center: Point { x: 0.0, y: 0.0 },
        radius: 5.0,
    };
    print("Center x: " + circle.center.x);
}

4. Understanding Diameter Logic

Diameters model dialectical tension between two opposing poles. Create diameter.br:

// Define a diameter with two poles
diameter resource_allocation: {
    pole efficiency: {
        // Thesis: maximize efficiency
        return 0.9;
    }
    pole quality: {
        // Antithesis: maximize quality
        return 0.7;
    }
}

fn main() {
    // Step 1: Observe the initial state
    let initial_tension = resource_allocation.observe("tension");
    let initial_state = resource_allocation.observe("state");
    print("Initial tension: " + initial_tension);
    print("Initial state: " + initial_state);

    // Step 2: Evolve the diameter (synthesis)
    let i = 0;
    while i < 5 {
        resource_allocation.evolve();
        let tension = resource_allocation.observe("tension");
        let state = resource_allocation.observe("state");
        print("Step " + i + ": tension=" + tension);
        i = i + 1;
    }

    // Step 3: Use the synthesis value
    let final_tension = resource_allocation.observe("tension");
    if final_tension > 0.5 {
        print("High tension - need intervention");
    } else {
        print("Balanced state");
    }
}

Key concepts:

  • pole defines opposing forces in the diameter
  • observe("tension") returns the dialectical tension (0.0-1.0)
  • observe("state") returns the current synthesis value
  • evolve() advances the dialectical process

5. Training an LLM

This tutorial walks through defining and training a small language model. Create train_llm.br:

// Step 1: Define the model architecture
model tiny_llm = Transformer {
    vocab_size: 50257;
    d_model: 128;
    num_layers: 2;
    num_heads: 4;
    d_ff: 512;
    dropout: 0.1;
    activation: "gelu";
    learning_rate: 0.001;
    batch_size: 4;
    seq_len: 64;
    num_epochs: 1;
    seed: 42;
}

// Step 2: Define custom training with diameter guidance
diameter training_focus: {
    pole explore: {
        return 0.3;  // Explore new patterns
    }
    pole exploit: {
        return 0.8;  // Exploit known patterns
    }
}

fn main() {
    print("Starting LLM training...");

    // Step 3: Run the training loop
    let epoch = 0;
    while epoch < tiny_llm.num_epochs {
        print("Epoch " + epoch);

        // Step 4: Train for this epoch
        // (In production, use std.train.run(tiny_llm) for the full pipeline)
        training_focus.evolve();
        let balance = training_focus.observe("state");
        print("Training balance: " + balance);

        epoch = epoch + 1;
    }

    print("Training complete!");
}

// For production training using the C API directly:
// fn c_api_example() {
//     let cfg = TrainConfig {
//         d_model: 128, d_ff: 512,
//         num_layers: 2, num_heads: 4,
//         vocab_size: 50257, batch_size: 4,
//         seq_len: 64, total_steps: 100,
//         learning_rate: 0.001,
//         checkpoint_dir: "./checkpoints",
//     };
//     train_cpu_only(cfg);
// }

Run the training:

braidc run train_llm.br

The training pipeline uses:

  • CPU streaming engine — processes token sequences through transformer blocks
  • Hierarchical head — tree-based classification head for loss computation
  • Block critics — per-layer LoRA-style local learning updates
  • Diameter training state — dialectical guidance for the training process
  • Checkpoint system — periodic saves for resuming interrupted training