Go ≥ 1.27 · v1.1.0 · Apache-2.0
Pipelines that say what they cost.
Kotlin and LINQ ergonomics on top of iter.Seq, built on Go 1.27 generic methods. Every operator declares its memory class, its termination behaviour, and what it does with errors — and a conformance suite proves each one.
top := catena.FromSlice(orders).
Filter(func(o Order) bool { return o.Paid }).
TopNBy(10, func(o Order) int { return o.Amount })
byUser := catena.FromSlice(orders).FoldBy(
func(o Order) UserID { return o.User },
func(UserID) int { return 0 },
func(sum int, o Order) int { return sum + o.Amount },
)
go get github.com/NerdMeNot/catena
Nothing is hidden
No reflect, no any in value position, no hidden goroutines, no hidden
buffering. An operator that buffers says so in its doc comment, with its bound; a
terminal that would hang on an infinite sequence is marked; every panic happens at
construction, at the line that made the mistake.
Contracts tested, not promised
Every exported operator is registered in a conformance harness that consumes it
twice, runs it over infinite sources, breaks early and checks the producer’s cleanup
ran, and compares it against a hand-written loop. A completeness check fails CI for
any operator nothing registers. Statement coverage is 100%, enforced.
Slow only where Go is slow
Benchmarked against the same pipelines hand-built from raw iter.Seq
closures, catena meets or beats the raw mechanism on every path — the library adds
nothing. What remains against a plain loop is the iterator protocol itself, and it
is published rather than waved at.