Lo - A Go library for functional programming

website·Indexed 32 days ago

https://lo.samber.dev

A production-ready Go library built on Go 1.18+ generics providing Lodash-style utility functions for slices, maps, strings, channels, and functions. It includes helpers for collection manipulation, concurrency, error handling, sequence operations, and in-place mutation tools for memory efficiency.

Tokens
4.2K
Snippets
2
Records
32
Agent score
13%

What's inside Lo

  1. Overview of the Lo functional programming library

    Lo is a production-ready Go library built on Go 1.18+ generics that provides over 300 Lodash-style utility functions. It is designed to be a zero-dependency replacement for common collection manipulation, concurrency, and error handling patterns, offering compile-time type safety and minimal runtime overhead.
  2. Use lazy evaluation and streaming with lo/it

    The lo/it package provides iterator helpers for lazy evaluation and streaming operations on sequences. It is organized into several functional categories:
  3. Optimize Lo for production performance

    When working with large datasets or CPU-bound operations in production, follow these optimization strategies:

    • Use the lo/it package for large datasets to reduce memory overhead.
    • Use the lo/parallel package for CPU-bound operations on large collections.
    • Use iterators for datasets that are too large to fit in memory (streaming).
    • Profile code using Go's built-in profiling tools to identify specific bottlenecks.
    • Select specialized helper variants when available for specific use cases.
  4. Implement functional control flow and concurrency

    The lo library extends Go's control flow with functional patterns and concurrency helpers:

    • Conditional Logic: lo.If().ElseIfF().Else() provides a fluent interface for conditional values.
    • Error Handling: lo.TryOr provides a fallback value if a function returns an error. lo.AttemptWithDelay implements retry logic with a specified delay.
    • Concurrency: lop.Map allows parallel processing of datasets. lo.NewDebounce limits the rate of function execution.
    • Transactions: lo.NewTransaction manages operations that can be rolled back.
    // Elegant conditional logic
    message := lo.If(user != nil, "Welcome back!").
        ElseIfF(isGuest, func() string { return "Welcome guest!" }).
        Else("Please login")
    
    // Retry logic with delay
    result, err := lo.AttemptWithDelay(3, time.Second, func(i int, d time.Duration) error {
        return callExternalAPI(context.Background())
    })
    
    // Parallel processing
    results := lop.Map(items, func(item Item) Result {
        return processItem(item) 
    })
  5. Optimize memory and performance with lo

    For performance-critical applications, lo offers several strategies:

    • In-place Mutation: Use the lo/mutable sub-package for operations that modify slices in-place to reduce allocations.
    • Lazy Evaluation: Use the lo/iter sub-package for streaming large datasets via iterator patterns.
    • Zero-copy: Many core helpers are designed to avoid unnecessary allocations and utilize linear memory access for CPU cache efficiency.
  6. Collection search and retrieval helpers in the lo package

    Lo provides extensive helpers for finding elements in slices and maps:

    • Indexing: IndexOf, LastIndexOf, Nth, NthOr, NthOrEmpty.
    • Predicates: Find (first match), FindIndexOf, FindLastIndexOf, FindOrElse.
    • Map Search: FindKey (by value), FindKeyBy (by predicate).
    • Uniques/Duplicates: FindUniques, FindUniquesBy, FindDuplicates, FindDuplicatesBy.
    • Extremes: Min, Max, MinBy, MaxBy, MinIndex, MaxIndex, Earliest, Latest.
    • Random Sampling: Sample, SampleBy, Samples, SamplesBy.
    • Prefix/Suffix: HasPrefix, HasSuffix.
  7. Error handling and panic recovery helpers in the lo package

    The lo package includes helpers to streamline Go's error handling and manage panics:

    • Validate: Returns an error if a condition is false.
    • Must (and Must0-Must6): Panics if an error is not nil; otherwise, returns the value(s).
    • Try (and Try0-Try6): Executes a function and panics on error.
    • TryOr (and TryOr1-TryOr6): Executes a function and returns a fallback value if an error occurs.
    • TryCatch / TryCatchWithErrorValue: Executes a function with panic recovery.
    • TryWithErrorValue: Executes a function and converts a panic into an error value.
    • Assert / Assertf: Panics if a condition is false, with optional formatted messaging.
  8. Concurrency and synchronization helpers in the lo package

    Lo provides utilities to simplify goroutine management and synchronization:

    • Synchronize: Coordinates multiple goroutines using a mutex.
    • Async (and Async0-Async6): Executes a function in a goroutine and returns a channel for the result (supporting 0 to 6 return values).
    • WaitFor: Blocks execution until a specific condition becomes true.
    • WaitForWithContext: Blocks until a condition is true or the provided context is cancelled.
  9. Function partial application in the lo package

    The lo package allows creating new functions by pre-filling arguments of an existing function using Partial and its variants Partial1 through Partial5.
  10. Conditional logic helpers in the lo package

    The lo package provides functional alternatives to standard conditional statements:

    • Ternary/TernaryF: Return a value (or result of a function) based on a condition.
    • If/IfF: Return a value if a condition is true.
    • ElseIf/ElseIfF: Return a value if the previous condition was false and the current one is true.
    • Else/ElseF: Return a value if all previous conditions were false.
    • Switch/Case/CaseF/Default/DefaultF: Implement a functional switch-case structure.
  11. Set operations and intersection helpers in the lo package

    The lo package provides utilities for comparing and combining collections:

    • Membership: Contains, ContainsBy.
    • Quantifiers: Every (all match), Some (any match), None (none match), and their By variants using predicates.
    • Set Logic: Intersect (common elements), Difference (elements in first but not others), Union (all unique elements).
    • Removal: Without (remove specific elements), WithoutBy (remove by predicate), WithoutNth (remove by index).
    • Comparison: ElementsMatch, ElementsMatchBy.
  12. Manipulate types and pointers in sequences

    Lo provides helpers to transition between typed sequences and pointers or generic types:

    • ToSeqPtr: Converts a sequence to a sequence of pointers.
    • FromSeqPtr: Converts a sequence of pointers back to a sequence.
    • FromSeqPtrOr: Converts a sequence of pointers to a sequence, providing a fallback for nil pointers.
    • ToAnySeq: Converts a typed sequence to []any.
    • FromAnySeq: Converts []any back to a typed sequence.
    • IsEmpty / IsNotEmpty: Boolean checks for sequence length.
    • CoalesceSeq: Returns the first non-empty sequence from a list of sequences.