Chapter 1.1: Hello World
Welcome to Ferrite! Let's start with the classic first program.
In Ferrite, you can use the built-in
println function to output text to the console.
println("Hello, World!");
Try in Playground →
Chapter 1.2: Variables & Types
Ferrite is strictly typed. You must declare the type of a
variable. By default, variables are declared with the
keep keyword.
keep age: int = 25;
keep name: string = "Ferris";
keep is_active: bool = true;
keep pi: float = 3.14159;
Variables are immutable constants by default. You can reassign them if you want, but their type can never change.
keep count: int = 1;
count = count + 1; // Allowed
// count = "two"; // Error: Type mismatch
Chapter 2.1: If & Else
Conditional logic in Ferrite uses standard if,
else if, and else blocks. Note that
there are no parentheses around the condition!
keep score = 85;
if score >= 90 {
println("Grade: A");
} else if score >= 80 {
println("Grade: B");
} else {
println("Grade: C");
}
Chapter 2.2: Loops
Ferrite primarily uses while loops for iteration.
You can use skip to continue to the next
iteration, and stop to break out of the loop.
keep i = 0;
while i < 5 {
i = i + 1;
if i == 3 {
skip; // Skips printing 3
}
println("Count: " + str(i));
}
Chapter 3.1: Enums & Match
Ferrite supports powerful algebraic datatypes using
enum, and deep pattern matching with the
match keyword.
You can also use if clauses inside match arms as
"guards" for extra conditions!
enum Result<T> {
Ok(T);
Err(string);
}
keep response = Ok(200);
match response {
case Ok(status) if status == 200 => {
println("Success!");
}
case Ok(status) => {
println("Other status: " + str(status));
}
case Err(msg) => {
println("Error: " + msg);
}
}
Chapter 4.1: Groups
Instead of classes or structs, Ferrite uses
group to define collections of data.
group Vector2 {
x: float;
y: float;
}
keep position = Vector2 { x: 10.5, y: 20.0 };
println("X Coordinate: " + str(position.x));
Chapter 4.2: Traits (Interfaces)
A trait defines shared behavior (like an
interface). You can then use the impl block to
implement that behavior for a specific group.
trait Display {
fun format(self) -> string;
}
impl Display for Vector2 {
fun format(self) -> string {
return "Vec2(" + str(self.x) + ", " + str(self.y) + ")";
}
}
println(position.format());
Chapter 5.1: Tensors
Tensors are native primitives in Ferrite. When you declare a Tensor, you specify its shape in the type signature. The compiler checks these shapes during compile time!
import "math";
// Define a 1x4 input tensor and a 4x2 weights tensor
param inputs: Tensor<float, (1, 4)> = rand(1, 4);
param weights: Tensor<float, (4, 2)> = ones(4, 2);
// Matrix multiplication using the @ operator
// Resulting shape will automatically be (1, 2)
keep outputs = inputs @ weights;
Chapter 5.2: Execution Blocks
Ferrite uses specialized contexts for ML operations. For
example, infer {} blocks optimize execution for
pure feed-forward passes by disabling gradient tracking
overhead.
infer {
keep outputs = inputs @ weights;
println("Outputs: " + str(outputs));
}
train {
// Operations here will track gradients
keep loss = compute_gradients(inputs);
}