BRAIDGROUP
RESEARCH & DEV
17. Documentation

Attributes and Annotations

Decorator Syntax

Braid uses the @ symbol as a decorator prefix for attributes that modify the behavior of functions, structs, and other declarations. The compiler recognizes these annotations and emits the corresponding runtime instructions.

@decorator_name
fn my_function() {
    // ...
}

@decorator_name
struct MyStruct {
    // ...
}

@autograd — Automatic Differentiation

The @autograd decorator marks a function for automatic differentiation. This enables gradient computation, making the function differentiable for use in ML training loops. The compiler generates a gradient counterpart for the function.

@autograd fn loss_fn(x: float, y: float) -> float {
    return (x - y) * (x - y);
}

@autograd fn sigmoid(z: float) -> float {
    return 1.0 / (1.0 + exp(-z));
}

@autograd fn linear_transform(x: float, w: float, b: float) -> float {
    return w * x + b;
}

Under the hood, @autograd triggers OP_AUTOGRAD_FN in the VM. The function is wrapped so that every operation builds a computation graph that tracks gradients with respect to inputs.

@layer — Neural Network Layers

The @layer decorator turns a struct into a neural network layer with trainable parameters. Fields marked with @param become trainable tensors that the optimizer can update during training.

@layer struct Linear {
    @param weight = tensor_init(128, 64);
    @param bias = tensor_init(128);

    fn forward(self, x: tensor) -> tensor {
        return x @ self.weight + self.bias;
    }
}

@layer struct LayerNorm {
    @param gamma = tensor_init(64);
    @param beta = tensor_init(64);

    fn forward(self, x: tensor) -> tensor {
        let mean = x.mean();
        let std = x.std();
        return self.gamma * (x - mean) / std + self.beta;
    }
}

The @layer decorator causes the VM to emit OP_LAYER_STRUCTand register the struct as a layer that participates in automatic differentiation and optimizer updates.

@param — Trainable Parameters

Inside @layer structs, individual fields can be marked with@param to designate them as trainable parameters. They are initialized with a tensor expression and automatically tracked for gradient computation.

@layer struct Attention {
    @param q_weight = tensor_init(64, 64);
    @param k_weight = tensor_init(64, 64);
    @param v_weight = tensor_init(64, 64);
    @param output_weight = tensor_init(64, 64);

    fn forward(self, x: tensor) -> tensor {
        let q = x @ self.q_weight;
        let k = x @ self.k_weight;
        let v = x @ self.v_weight;
        let scores = q @ k.transpose() / sqrt(64.0);
        let attn = scores.softmax();
        return attn @ v @ self.output_weight;
    }
}

@model — ML Model Definitions

The model keyword (used without @) defines a complete ML model configuration. It specifies the architecture type and hyperparameters.

model my_llm = Transformer {
    vocab_size: 50257;
    d_model: 512;
    num_layers: 6;
    num_heads: 8;
    d_ff: 2048;
    dropout: 0.1;
    activation: "gelu";
    learning_rate: 0.001;
    batch_size: 8;
    seq_len: 512;
    num_epochs: 5;
    seed: 42;
}

Model definitions are parsed as AST_MODEL_DEF nodes and configure the runtime's ML execution context.

Compiler Handling

The parser recognizes the @ token and looks ahead for known decorator names. Unknown decorators produce a compile error.

  • @autograd produces AST_AUTOGRAD_DECL
  • @layer produces AST_LAYER_DECL
  • @param produces AST_PARAM_FIELD inside layer structs