go-functional

module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 5, 2026 License: Apache-2.0

README

Go Reference CI workflow

go-functional

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.

Installation

go get github.com/mikehelmick/go-functional

Packages

Functional primitives
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
OTP-inspired concurrency

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

Quick examples

Slice operations
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]
Task — concurrent work
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 order
Agent — shared mutable state
counter := agent.New(0)
counter.Update(func(n int) int { return n + 1 })
fmt.Println(counter.Get()) // 1
counter.Stop()
Supervisor — automatic restart
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()
GenServer — serialised state with call/cast
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()

Example application

See examples/wordfreq for an OTP-style word frequency service that combines supervisor, agent, task, pipeline, slice, and maps.

Attribution

Parts of this library were written with the assistance of Claude Code.

Directories

Path Synopsis
Package agent provides a goroutine-safe state container inspired by Elixir's Agent.
Package agent provides a goroutine-safe state container inspired by Elixir's Agent.
examples
circuitbreaker command
Command circuitbreaker demonstrates using genserver to implement a circuit breaker — a resilience pattern that stops cascading failures by fast-failing requests when a downstream dependency is unhealthy.
Command circuitbreaker demonstrates using genserver to implement a circuit breaker — a resilience pattern that stops cascading failures by fast-failing requests when a downstream dependency is unhealthy.
wordfreq command
Command wordfreq is an OTP-style word frequency service demonstrating how go-functional's concurrency primitives compose:
Command wordfreq is an OTP-style word frequency service demonstrating how go-functional's concurrency primitives compose:
Package genserver provides a generic server process inspired by Elixir's OTP GenServer.
Package genserver provides a generic server process inspired by Elixir's OTP GenServer.
Package map provides functional abstractions over go maps.
Package map provides functional abstractions over go maps.
Package optional provides a Maybe type representing an optional value.
Package optional provides a Maybe type representing an optional value.
Package pipeline provides function composition utilities.
Package pipeline provides function composition utilities.
Package result provides a Result type representing either a successful value or an error.
Package result provides a Result type representing either a successful value or an error.
Package slice provides functional abstractions over go slices.
Package slice provides functional abstractions over go slices.
Package supervisor provides a supervised goroutine manager inspired by Elixir's OTP Supervisor.
Package supervisor provides a supervised goroutine manager inspired by Elixir's OTP Supervisor.
Package task provides typed asynchronous work units inspired by Elixir's Task module.
Package task provides typed asynchronous work units inspired by Elixir's Task module.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL