diff --git a/lib/CLAUDE.md b/lib/CLAUDE.md new file mode 100644 index 00000000..7b7edace --- /dev/null +++ b/lib/CLAUDE.md @@ -0,0 +1,35 @@ +lib/ — Hare-shaped standard library, deliberately a subset. + +Scope: every `lib/*` directory except `lib/ww/`, which is the compiler +frontend port and has its own rules (see `lib/ww/CLAUDE.md`). + +Names mirror Hare. Before adding a function, find its counterpart in +`ref/hare//` and copy the name verbatim (`strings.compare`, +`bytes.index`, `strconv.stoi64`, `io.read`, `path.init`). Don't +invent. Don't shorten. Don't reorder parameters. + +Signatures are intentionally a Plan 9 / pre-tagged-union subset, +because the wwstage compiler doesn't yet have ergonomic tagged-union +returns or full variadic ABI: + +- `i32` with `-1` sentinel stands in for Hare's `(size | void)` and + `(size | io::EOF)`. Example: `bytes.indexbyte(s, c) i32` returning + `-1` for not-found. +- Plain `str` errors stand in for tagged error types (`invalid`, + `overflow`, `io::error`). Example: `strconv.parse64(s) (i64 | str)` + where the `str` is the message Hare would have tagged. +- `lib/fmt` is print/println-only — printf-family waits on a variadic + ABI. +- Allocation-free at the boundary: where Hare returns a freshly- + allocated slice, take a caller-supplied buffer. No GC, and the `rt` + allocator is not a stable public surface yet. + +Don't ship a richer surface than Hare has. A documented subset is +fine; an extension, rename, or convenience-wrapper is not — return +shapes will change as the compiler gains tagged unions, variadics, +and a stable `rt` allocator, and callers should not bake the current +subset shape into themselves. + +When the compiler can express the full Hare signature, graduate the +module — replace the `-1` / `str` shape with the tagged-union shape +in one go and fix the callers. Don't keep both around.