Skip to content

Latest commit

 

History

History
55 lines (48 loc) · 3.69 KB

File metadata and controls

55 lines (48 loc) · 3.69 KB

CLAUDE.md

Gofu is a Go 1.27+ generic collections library providing fluent, type-safe functional data transformations for slices and maps — Map, Filter, Reduce, FlatMap, GroupBy, Partition, SortBy, and more. It provides the same API for sequential (Slice) and parallel (ParallelSlice) code. Zero reflection or interface{}.

Build/Test

  • go build ./... — build all packages
  • go test ./... -v -count=1 — run all unit tests (root + test/)
  • go vet ./... — vet
  • golangci-lint run ./... — lint
  • go run ./examples/slice/main.go — run slice example
  • go run ./examples/map/main.go — run map example
  • go run ./examples/starwars/main.go — run starwars example (SWAPI)
  • go run ./examples/rickandmorty/main.go — run rickandmorty example (R&M API)

Architecture

  • slice.go, map.go — type definitions (Slice[T], Map[K,V], Entry[K,V], ParallelSlice[T])
  • *_read.go — read-only queries (Count, First, Find, ContainsFunc)
  • *_transform.go — immutable transforms (Map, Filter, Reduce, GroupBy)
  • *_mut.go — in-place mutation (Delete, Reverse, Compact, Shuffle, Filter)
  • *_loop.go — chunk-based helpers (MapChunks)
  • parallel_slice*.go — concurrent slice operations
  • map_join.go — set ops (Merge, Intersect, Difference)
  • test/slice/, test/map/ — unit tests (one file per method)
  • examples/slice/, examples/map/ — runnable examples

Code Style

  • Formatter: gofumpt + gci (golangci-lint run --fix)
  • Go 1.27: generic methods on generic types. No reflection/interface{}.
  • No interfaces: return concrete types (Slice[T], ParallelSlice[T]).
  • Value receivers on all methods.
  • Immutability: methods return new collections. Opt-in mutation via .Mut().
  • Sharing allowed: some methods share backing arrays. Call Copy() for independence.
  • Type inference: prefer inferred over explicit type params.
  • Doc comments: methods use // Name description. [ Immutable | Mutates | ReadOnly ] [ time: O(...); space: O(...) ] — short sentence, then blank line, then detail. No implementation details. No unexported refs. Types must NOT carry [IMMUTABLE|MUTATES|READONLY] tags.
  • No em dashes: use ASCII -.
  • Tests: data-driven table tests. See tests.md for rules. Use assert.Eq/assert.EqSlice from test/assert/.
  • Mutation methods (in-place): .Reverse(), .Delete(), .Compact(), .Shuffle(). For Slice/Map: .Mut().Filter() returns original type. Map also has .Mut().Delete(key) and .Mut().DeleteFunc(pred).
  • Generic instantiation cycles: always wrap public method results in Map/Slice constructors. Use direct slice indexing where possible.

README Method Ordering

  1. Generic methods first (Map[R], FlatMap[R], Reduce[R], ToMap[K,V], GroupBy[K], DistinctBy[K], IndexBy[K], MapChunks[R], ToSlice[S])
  2. Non-generic transforms (Filter, Partition)
  3. Mut-counterparts at bottom (Reverse, SortBy, Shuffle)
  4. Least logic last (Copy, Collect)
  5. Group by naming (Map/FlatMap/ToMap, First/FirstOr, Merge/Intersect, Keys/Values)

Don'ts

  • No reflection or interface{}
  • Don't call unexported helpers (mapNoAlloc, collectMapResults, shouldSequential)
  • Don't mix MUTATES and IMMUTABLE — Copy() first if you need the original after mutation
  • Don't commit unless asked

Implementation Decisions

  • Map.Difference: maps.Clone + delete loop (faster at low/moderate overlap vs insert-only; insert-only only wins at 90%+ overlap).
  • No interfaces: Go 1.27 doesn't support type params on interface methods, so return concrete types for full chaining without type assertions.