Generics
Why This Matters
Generics let you reuse logic without sacrificing compile-time type guarantees.
Core Idea
Write one definition that works for many concrete types.
Current scope:
- user-defined generic functions/classes/interfaces are supported
- user-defined generic enums are not supported yet
Generic Functions
function identity<T>(value: T): T {
return value;
}
function main(): None {
a: Integer = identity<Integer>(10);
return None;
}
Type arguments can often be inferred when context is strong enough.
Generic Classes
class Box<T> {
value: T;
constructor(value: T) {
this.value = value;
}
function get(): T {
return this.value;
}
}
Generic Interfaces
interface Reader<T> {
function read(): T;
}
Constraints (extends)
Use interface bounds to require capabilities:
import std.io.*;
interface Named { function name(): String; }
function printName<T extends Named>(value: T): None {
println(value.name());
return None;
}
Bounds are interface-based; invalid/unknown/non-interface bounds are rejected.
Nested Generic Types
Generic types compose naturally:
Option<List<Integer>>Result<Map<String, Integer>, String>
Practical Guidance
- add generic parameters only when reusability is real
- keep bounds minimal and meaningful
- prefer explicit type args when readability is improved