Vibeleaderboard
Index / tool
Visit github.com
Category
Developer Tools
Rank
Pricing
Open Source
Type
TOOL
GitHub
1 stars
Latest release
v1.5.0
Date

About

catena is a Go library providing lazy, fully typed sequence pipelines over the standard library's iter.Seq, adding chained filter, map, fold, grouping and top-N operations plus a parallel worker-pool helper and a Try type that lets the caller choose how to handle errors mid-pipeline. It targets Go 1.27's generic methods to give Kotlin- or LINQ-like chaining without reflection, hidden goroutines or extra buffering beyond plain iter.Seq closures.

What it does

catena turns the loops Go programmers keep writing by hand (total these rows per customer, keep the ten biggest, call a slow service eight at a time, decide what a bad record means) into a chain of named steps that reads top to bottom. Nothing runs until the end of the chain asks for results, so a search that stops after five matches reads only as far as it needs to. Failures can travel through the chain as ordinary items, and the code at the end picks whether to abort, collect them, or skip them. Concurrency sits in a separate package that waits for every background task before returning.

Why it's ranked here

A narrow Go library that documents its own costs more precisely than most. It is Apache 2.0 with no runtime dependencies, and its performance guide publishes where it loses: a four-step chain runs about ten times slower than a plain loop doing trivial arithmetic, and two operators trail a hand-built baseline by 9% and 24%. Where it wins, it wins on memory: keeping the top ten of 100,000 items drops from 1.7 MB to about 1 KB in the project's own benchmarks. The claims of full statement coverage and a per-operator conformance check come from the README; the verdict is positive for data-shaping code, with that caveat.

What's good

Error handling stands out. A failed parse or fetch becomes one item in the stream, and the caller chooses at the end to stop at the first error, gather all of them, or drop them, without rewriting anything. Files and database rows are opened only when the chain runs and closed even when a later step stops early; the docs say this is tested against a real database driver. Bad arguments fail immediately with a message naming the step. Every operator states how much memory it holds and whether it hangs on endless input. Collecting results avoids recopying, where plain growth allocated 4.1 MB to return 800 KB.

Tradeoffs

It requires Go 1.27, and adding it raises your own module's minimum Go version, so every teammate and build machine needs that toolchain. Chains cost real time on cheap work: about 2.4 nanoseconds per item across four steps, which only disappears when each step does I/O, parsing or allocation. Pairing two sequences element by element uses a runtime coroutine at roughly 35 nanoseconds per item. Sequences are not safe to share across goroutines, and many sources can be read only once; a second read silently yields nothing unless you add the development guard. Version 1.0.0 and the 0.x tags are withdrawn; old pins must move to 1.1.0 or later.

How to use it well

Reach for it in Go services already on 1.27 that reshape data from files, SQL rows, paginated APIs or slow network calls, where the hand-written version tangles error handling, counters and cleanup together. Learn the per-key fold and the bounded top-N first: those change memory use, not just style. Pick an error policy as soon as failures stop mattering and drop back to the full operator set. Keep plain loops for hot arithmetic on small slices; the project says so itself. Run the companion linter to find sort-everything-then-take-ten patterns. It is not a dataframe or query engine, and it does not make shared sequences safe for concurrent use.

Technical notes+

catena.go defines four types over the standard library: Seq[T] as a defined iter.Seq[T], Seq2[K, V], Try[T] as iter.Seq2[T, error], and List[T] as []T. Operators consume their source through a small inlinable each method instead of a range statement; docs/05-performance.md credits that for Sum dropping from 71µs to 24µs and for the 4-stage pipeline beating raw closures (261µs vs 353µs, Apple M5 Max, 100k elements). The gatherer type in catena.go appends up to gatherSwitchAt (1024) elements, then fills fixed 8192-element blocks and copies once at the end. go.mod declares go 1.27, retracts v0.1.0 through v0.3.0 and v1.0.0, and requires only pgregory.net/rapid v1.3.0, used for property tests. docs/03-error-handling.md fixes five rules for Try (intermediates skip errored elements, Take counts them, single-error terminals stop at the first) and warns that Pull without calling stop never runs the producer's defers.

Observed

License
Apache-2.0
Language
Go, minimum toolchain 1.27 (declared in go.mod)
Runtime dependencies
None; the single require in go.mod is a test-only property-testing library
Interface
Go library, installed with go get; companion catenalint linter ships as a separate module
Packages
Core catena, plus catena/parallel (goroutine operators) and catena/source (lines, pagination, SQL rows)
Retracted versions
go.mod retracts v0.1.0 through v0.3.0 and v1.0.0
Concurrency safety
Package doc states sequences are not safe for concurrent use
Coverage claim
README states CI fails the build below full statement coverage

Read from README.md, go.mod, LICENSE, catena.go, docs/01-getting-started.md, docs/02-concepts.md, docs/05-performance.md, docs/03-error-handling.md, examples/01-basics/main.go.

Tags

goiteratorsgenericsfunctional-programmingconcurrencylibrary

Tech Stack

Go

Media

catena

Comments (0)

No comments yet

Editorially curated, with community endorsements as a secondary signal. Corrections welcome.