Data Types¶
Raven is a statically-typed language with a rich type system that provides safety and expressiveness.
Primitive Types¶
Integer (int)¶
64-bit signed integers.
let age: int = 25;
let count: int = -10;
let maxValue: int = 9223372036854775807;
Float (float)¶
64-bit floating-point numbers.
let pi: float = 3.14159;
let temperature: float = 98.6;
let precision: float = 0.001;
Boolean (bool)¶
True or false values.
let isActive: bool = true;
let isComplete: bool = false;
let isValid: bool = (age > 18);
string (string)¶
UTF-8 encoded strings. Inside double-quoted literals, backslash escapes are supported (for example \", \\, \n, \r, \t, \0), so JSON-like payloads such as "{\"hello\":1}" parse as a single string value.
let name: string = "Alice";
let message: string = "Hello, World!";
let empty: string = "";
let json: string = "{\"hello\":1}";
Array Types¶
Arrays are collections of elements of the same type.
Integer Arrays¶
let numbers: int[] = [1, 2, 3, 4, 5];
let emptyNumbers: int[] = [];
let singleNumber: int[] = [42];
string Arrays¶
let names: string[] = ["Alice", "Bob", "Charlie"];
let words: string[] = ["Hello", "World"];
Boolean Arrays¶
let flags: bool[] = [true, false, true];
let results: bool[] = [];
Multi-dimensional arrays¶
Array types nest: each [] adds one dimension. Element types must match at every level.
// 2D: matrix of int
let grid: int[][] = [[1, 2, 3], [4, 5, 6]];
let empty2d: int[][] = []; // zero rows
let rows: int[][] = [[], []]; // two empty rows (needs explicit int[][])
// 3D and deeper
let cube: int[][][] = [[[1, 2]], [[3, 4]]];
Indexing chains left-to-right: matrix[row][col] reads an element; matrix[row][col] = value assigns to that cell. The same works for struct fields that hold arrays, for example point.values[i][j] = x.
Type checking: nested literals like [[], []] are only valid when the variable has an explicit multi-dimensional type (for example int[][]), so the checker knows each inner [] is an int[].
User-Defined Types¶
Structs¶
Custom data structures with named fields.
struct Person {
name: string,
age: int,
isActive: bool
}
struct Point {
x: float,
y: float
}
// Usage
let person: Person = Person {
name: "Alice",
age: 25,
isActive: true
};
let point: Point = Point { x: 10.5, y: 20.0 };
Struct Methods¶
Structs can have methods defined with impl blocks. Each method receives self as the first parameter.
struct Person {
name: string,
age: int
}
impl Person {
fun greet(self) -> string {
return format("Hello, {}!", self.name);
}
fun have_birthday(self) -> void {
self.age = self.age + 1;
}
}
let p: Person = Person { name: "Alice", age: 30 };
print(p.greet()); // "Hello, Alice!"
p.have_birthday(); // Mutates p in place
- Methods must have
selfas the first parameter selfrefers to the struct value the method is called on- Mutations to
selfpersist when the receiver is a variable
Enums¶
Custom types with a set of named variants.
enum HttpStatus {
OK,
NotFound,
InternalError,
BadRequest
}
enum Color {
Red,
Green,
Blue,
Yellow
}
// Usage
let status: HttpStatus = HttpStatus::OK;
let color: Color = Color::Red;
Type Inference¶
Raven can infer types in some cases, but explicit typing is recommended for clarity.
// Explicit typing (recommended)
let name: string = "Alice";
let age: int = 25;
// Type inference (works but less clear)
let name = "Alice"; // Inferred as string
let age = 25; // Inferred as int
Type Checking¶
Raven performs static type checking at compile time.
let name: string = "Alice";
let age: int = 25;
// This would cause a type error:
// let result: int = name + age; // Error: can't add string and int
// Correct way:
let result: string = format("{} is {} years old", name, age);
Type Conversion¶
Raven provides built-in functions for type conversion.
let number: int = 42;
let text: string = format("{}", number); // Convert int to string
let input: string = "123";
// Note: Raven doesn't have built-in string-to-number conversion yet
// This would be added in future versions
Void Type¶
The void type represents the absence of a value, used for functions that don't return anything.
fun greet(name: string) -> void {
print(format("Hello, {}!", name));
// No return statement needed
}
Type Safety¶
Raven's type system prevents many common errors:
- No null pointers - All variables must be initialized
- No type confusion - Can't accidentally mix types
- Array bounds checking - Prevents buffer overflows
- Immutable by default - Variables can be reassigned but not mutated in place
Best Practices¶
- Always use explicit types for function parameters and return values
- Use descriptive names for struct fields and enum variants
- Initialize variables when declaring them
- Use appropriate types for your data (int for counts, float for measurements)
- Leverage type checking to catch errors early
Next: Control Flow - Conditional statements and loops