lang: Document explicit generics
2ef85b935c142fa09a913c950e26128828b01bbe1e232082afb485e73054a8ce
Describe generic declarations, specialization roots, trait bounds, integer parameters, and current limitations. Assisted-by: Codex:gpt-5.6
1 parent
1e75c95d
README
+52 -0
| 59 | 59 | ||
| 60 | 60 | Run a compiled binary: |
|
| 61 | 61 | ||
| 62 | 62 | emulator -run example.rv64 |
|
| 63 | 63 | ||
| 64 | + | GENERICS |
|
| 65 | + | ||
| 66 | + | Records, unions, and free functions declare ordered type or integer |
|
| 67 | + | parameters between `⟨` and `⟩`: |
|
| 68 | + | ||
| 69 | + | union Maybe⟨T⟩ { None, Some(T) } |
|
| 70 | + | record Buffer⟨const N: u32⟩ { data: [u8; N] } |
|
| 71 | + | fn first⟨T⟩(left: T, right: T) -> T { return left; } |
|
| 72 | + | ||
| 73 | + | Concrete data and function applications use the same syntax. |
|
| 74 | + | Every concrete application reachable at run time must be covered by an |
|
| 75 | + | explicit package-level monomorphization root and its dependency closure: |
|
| 76 | + | ||
| 77 | + | instantiate Maybe⟨u32⟩, first⟨u32⟩; |
|
| 78 | + | ||
| 79 | + | Rooted generic functions add generic callees and nested data applications to |
|
| 80 | + | the specialization closure. For declarations with only type parameters, |
|
| 81 | + | calls may omit the generic argument list when local parameter and result |
|
| 82 | + | evidence selects one already-rooted specialization; inference never creates |
|
| 83 | + | a root. Integer arguments are compile-time expressions. The compiler checks |
|
| 84 | + | each argument against its parameter's declared type. A declaration with |
|
| 85 | + | an integer parameter requires a complete argument list. |
|
| 86 | + | ||
| 87 | + | Type parameters may have trait bounds. Calls through those bounds use |
|
| 88 | + | static instance dispatch: |
|
| 89 | + | ||
| 90 | + | trait Less { fn (&Less) less(other: &Self) -> bool; } |
|
| 91 | + | fn minimum⟨T: Less⟩(a: T, b: T) -> T { |
|
| 92 | + | if a.less(&b) { return a; } |
|
| 93 | + | return b; |
|
| 94 | + | } |
|
| 95 | + | ||
| 96 | + | `Self` is the concrete instance type in trait signatures. Opaque trait |
|
| 97 | + | objects remain dynamic. The compiler rejects traits whose `Self` usage is |
|
| 98 | + | not object-safe. `instance` declares a trait implementation. `instantiate` |
|
| 99 | + | requests generic monomorphization. |
|
| 100 | + | ||
| 101 | + | Generic symbols follow ordinary module visibility. A root may reference an |
|
| 102 | + | exported template in another module by its qualified name: |
|
| 103 | + | ||
| 104 | + | use containers; |
|
| 105 | + | instantiate containers::Maybe⟨u32⟩; |
|
| 106 | + | ||
| 107 | + | Duplicate roots share one package-wide specialization. |
|
| 108 | + | ||
| 109 | + | Unsupported by design: generic traits, instances, or methods; associated |
|
| 110 | + | types; overlapping instances; user-defined specialization; arbitrary |
|
| 111 | + | compile-time execution; inferred roots; and higher-kinded types. The compiler |
|
| 112 | + | diagnoses wrong arity or argument kind, unsatisfied or ambiguous bounds, |
|
| 113 | + | missing roots, incomplete or conflicting inference, recursive layout, |
|
| 114 | + | expanding dependency chains, and implementation-limit overflow. |
|
| 115 | + | ||
| 64 | 116 | TESTING |
|
| 65 | 117 | ||
| 66 | 118 | Run all tests: |
|
| 67 | 119 | ||
| 68 | 120 | make test |