Functional programming primitives and OTP-inspired concurrency patterns for Go generics.
Requires Go 1.24+. See the documentation site for full API docs and examples.
go get github.com/mikehelmick/go-functional| Package | Description |
|---|---|
slice |
Filter, Map, Fold, Find, Zip, Chunk, Sort, Dedup, Scan, and more |
maps |
MapValues, FilterMap, Merge, MergeWith, Invert, Keys, ToSlice |
optional |
Maybe[T] — Some or None with Map and GetOrElse |
result |
Result[T] — wraps (T, error) with Map and chaining |
pipeline |
Function composition: Pipe, Pipe2, Pipe3, Pipe4 |
Inspired by Elixir's OTP abstractions. Each package provides a typed, goroutine-safe building block.
| Package | Description |
|---|---|
agent |
Goroutine-owned mutable state with Get / Update / Cast |
genserver |
Generic request/response server loop — Call (sync) and Cast (async) |
task |
Typed async work unit — Run, Await, AwaitAll, Map |
supervisor |
Managed goroutine restart with OneForOne and OneForAll strategies |
nums := []int{1, 2, 3, 4, 5, 6}
evens := slice.Filter(nums, func(n int) bool { return n%2 == 0 }) // [2 4 6]
doubled := slice.Map(nums, func(n int) int { return n * 2 }) // [2 4 6 8 10 12]
sum := slice.FoldL(nums, 0, func(acc, n int) int { return acc + n }) // 21
top3 := slice.Take(slice.SortBy(nums, func(n int) int { return -n }), 3) // [6 5 4]tasks := []*task.Task[int]{
task.Run(func() (int, error) { return expensiveA() }),
task.Run(func() (int, error) { return expensiveB() }),
task.Run(func() (int, error) { return expensiveC() }),
}
results, err := task.AwaitAll(tasks) // waits for all, returns in ordercounter := agent.New(0)
counter.Update(func(n int) int { return n + 1 })
fmt.Println(counter.Get()) // 1
counter.Stop()sup := supervisor.Start(supervisor.OneForOne, []supervisor.ChildSpec{
{
Name: "worker",
Start: func(ctx context.Context) error {
// Runs until ctx is cancelled.
// Returning a non-nil error triggers an automatic restart.
return runWorker(ctx)
},
},
})
defer sup.Stop()type CounterServer struct{}
func (CounterServer) Init() int { return 0 }
func (CounterServer) HandleCall(req string, n int) (int, int) { return n, n } // return current
func (CounterServer) HandleCast(req string, n int) int { return n + 1 } // increment
srv := genserver.Start[int, string, int](CounterServer{})
srv.Cast("inc")
srv.Cast("inc")
fmt.Println(srv.Call("get")) // 2
srv.Stop()See examples/wordfreq for an OTP-style word frequency service that combines supervisor, agent, task, pipeline, slice, and maps.
Parts of this library were written with the assistance of Claude Code.