Generics
Aria uses square brackets [T] for type parameters instead of angle brackets <T>. This eliminates the "turbofish" problem and all parsing ambiguity — a < b is always a comparison, never a generic.
Generic Functions
fn identity[T](x: T) -> T = x
fn first[T](items: [T]) -> T? {
if items.len() == 0 { None } else { Some(items[0]) }
}
fn map[T, U](list: [T], f: fn(T) -> U) -> [U] =
[f(x) for x in list]
fn zip[A, B](a: [A], b: [B]) -> [(A, B)] {
...
} Generic Types
type Pair[A, B] {
first: A
second: B
}
type Stack[T] {
items: [T]
}
// Built-in generic types
type Option[T] = Some(T) | None
type Result[T, E] = Ok(T) | Err(E) Trait Bounds
Constrain what types can be used:
// T must implement Ord
fn largest[T: Ord](items: [T]) -> T? {
...
}
// Multiple bounds with +
fn sortAndPrint[T: Ord + Display](items: [T]) {
sorted := items.sort()
for item in sorted {
println(item.display())
}
}
// Where clause for readability
fn merge[K, V]
where K: Eq + Hash, V: Clone {
...
} Generic Trait Implementations
impl[T: Display] Display for Stack[T] {
fn display(self) -> str {
items := self.items
.map(fn(x) => x.display())
.join(", ")
"Stack[{items}]"
}
}
impl[T: Display] Display for Option[T] {
fn display(self) -> str = match self {
Some(v) => "Some({v.display()})"
None => "None"
}
} Why Square Brackets?
In C++, Rust, and Java, angle brackets create parsing ambiguity:
// Is this a comparison or a generic?
a < b > c
// Rust needs the "turbofish" workaround
Vec::<i32>::new()
// C++ needs the "template" keyword in dependent contexts
typename Container<T>::iterator In Aria, there is zero ambiguity:
a < b // always a comparison
Stack[i64] // always a generic type
map[str, i64] // always a generic with two params For AI code generation, this eliminates an entire class of parsing errors.
Monomorphization
Generics are compiled via monomorphization — the compiler generates specialized code for each concrete type used. This means zero runtime overhead (no boxing, no vtables for generics).