golang-samber-lo
Original:🇺🇸 English
Translated
Functional programming helpers for Golang using samber/lo — 500+ type-safe generic functions for slices, maps, channels, strings, math, tuples, and concurrency (Map, Filter, Reduce, GroupBy, Chunk, Flatten, Find, Uniq, etc.). Core immutable package (lo), concurrent variants (lo/parallel aka lop), in-place mutations (lo/mutable aka lom), lazy iterators (lo/it aka loi for Go 1.23+), and experimental SIMD (lo/exp/simd). Apply when using or adopting samber/lo, when the codebase imports github.com/samber/lo, or when implementing functional-style data transformations in Go. Not for streaming pipelines (→ See golang-samber-ro skill).
8installs
Sourcesamber/cc-skills-golang
Added on
NPX Install
npx skill4agent add samber/cc-skills-golang golang-samber-loTags
Translated version includes tags in frontmatterSKILL.md Content
View Translation Comparison →Persona: You are a Go engineer who prefers declarative collection transforms over manual loops. You reach for to eliminate boilerplate, but you know when the stdlib is enough and when to upgrade to , , or .
loloplomloisamber/lo — Functional Utilities for Go
Lodash-inspired, generics-first utility library with 500+ type-safe helpers for slices, maps, strings, math, channels, tuples, and concurrency. Zero external dependencies. Immutable by default.
Official Resources:
This skill is not exhaustive. Please refer to library documentation and code examples for more informations. Context7 can help as a discoverability platform.
Why samber/lo
Go's stdlib and packages cover ~10 basic helpers (sort, contains, keys). Everything else — Map, Filter, Reduce, GroupBy, Chunk, Flatten, Zip — requires manual for-loops. fills this gap:
slicesmapslo- Type-safe generics — no casts, no reflection, compile-time checking, no interface boxing overhead
interface{} - Immutable by default — returns new collections, safe for concurrent reads, easier to reason about
- Composable — functions take and return slices/maps, so they chain without wrapper types
- Zero dependencies — only Go stdlib, no transitive dependency risk
- Progressive complexity — start with , upgrade to
lo/lop/lomonly when profiling demands itloi - Error variants — most functions have suffixes (
Err,MapErr,FilterErr) that stop on first errorReduceErr
Installation
bash
go get github.com/samber/lo| Package | Import | Alias | Go version |
|---|---|---|---|
| Core (immutable) | | | 1.18+ |
| Parallel | | | 1.18+ |
| Mutable | | | 1.18+ |
| Iterator | | | 1.23+ |
| SIMD (experimental) | | — | 1.25+ (amd64 only) |
Choose the Right Package
Start with . Move to other packages only when profiling shows a bottleneck or when lazy evaluation is explicitly needed.
lo| Package | Use when | Trade-off |
|---|---|---|
| Default for all transforms | Allocates new collections (safe, predictable) |
| CPU-bound work on large datasets (1000+ items) | Goroutine overhead; not for I/O or small slices |
| Hot path confirmed by | Mutates input — caller must understand side effects |
| Large datasets with chained transforms (Go 1.23+) | Lazy evaluation saves memory but adds iterator complexity |
| Numeric bulk ops after benchmarking (experimental) | Unstable API, may break between versions |
Key rules:
- is for CPU parallelism, not I/O concurrency — for I/O fan-out, use
lopinsteaderrgroup - breaks immutability — only use when allocation pressure is measured, never assumed
lom - eliminates intermediate allocations in chains like
loiby evaluating lazilyMap → Filter → Take - For reactive/streaming pipelines over infinite event streams, → see skill +
samber/cc-skills-golang@golang-samber-ropackagesamber/ro
For detailed package comparison and decision flowchart, see Package Guide.
Core Patterns
Transform a slice
go
// ✓ lo — declarative, type-safe
names := lo.Map(users, func(u User, _ int) string {
return u.Name
})
// ✗ Manual — boilerplate, error-prone
names := make([]string, 0, len(users))
for _, u := range users {
names = append(names, u.Name)
}Filter + Reduce
go
total := lo.Reduce(
lo.Filter(orders, func(o Order, _ int) bool {
return o.Status == "paid"
}),
func(sum float64, o Order, _ int) float64 {
return sum + o.Amount
},
0,
)GroupBy
go
byStatus := lo.GroupBy(tasks, func(t Task, _ int) string {
return t.Status
})
// map[string][]Task{"open": [...], "closed": [...]}Error variant — stop on first error
go
results, err := lo.MapErr(urls, func(url string, _ int) (Response, error) {
return http.Get(url)
})Common Mistakes
| Mistake | Why it fails | Fix |
|---|---|---|
Using | Unnecessary dependency for a stdlib-covered op | Prefer |
Using | Goroutine creation overhead exceeds transform cost | Use |
Assuming | | Use |
Using | | Use the non-Must variant and handle the error |
| Chaining many eager transforms on large data | Each step allocates an intermediate slice | Use |
Best Practices
- Prefer stdlib when available — ,
slices.Contains,slices.Sortcarry no dependency. Usemaps.Keysfor transforms the stdlib doesn't offer (Map, Filter, Reduce, GroupBy, Chunk, Flatten)lo - Compose lo functions — chain →
lo.Filter→lo.Mapinstead of writing nested loops. Each function is a building blocklo.GroupBy - Profile before optimizing — switch from to
lo/lomonly afterlopconfirms allocation or CPU as the bottleneckgo tool pprof - Use error variants — prefer over
lo.MapErr+ manual error collection. Error variants stop early and propagate cleanlylo.Map - Use only in tests and init — in production, handle errors explicitly
lo.Must
Quick Reference
| Function | What it does |
|---|---|
| Transform each element |
| Keep / remove elements matching predicate |
| Fold elements into a single value |
| Side-effect iteration |
| Group elements by key |
| Split into fixed-size batches |
| Flatten nested slices one level |
| Remove duplicates |
| First match or default |
| Membership tests |
| Extract map keys or values |
| Filter map entries |
| Pair/unpair two slices |
| Generate number sequences |
| Inline conditionals |
| Pointer helpers |
| Panic-on-error / recover-as-bool |
| Async execution / retry with backoff |
| Rate limiting |
| Fan-out to multiple channels |
For the complete function catalog (300+ functions), see API Reference.
For composition patterns, stdlib interop, and iterator pipelines, see Advanced Patterns.
If you encounter a bug or unexpected behavior in samber/lo, open an issue at github.com/samber/lo/issues.
Cross-References
- → See skill for reactive/streaming pipelines over infinite event streams (
samber/cc-skills-golang@golang-samber-ropackage)samber/ro - → See skill for monadic types (Option, Result, Either) that compose with lo transforms
samber/cc-skills-golang@golang-samber-mo - → See skill for choosing the right underlying data structure
samber/cc-skills-golang@golang-data-structures - → See skill for profiling methodology before switching to
samber/cc-skills-golang@golang-performance/lomlop