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.
@autogradproducesAST_AUTOGRAD_DECL@layerproducesAST_LAYER_DECL@paramproducesAST_PARAM_FIELDinside layer structs