tern is a small generic utility library for Go that brings ternary-like expressions and a variety of conditional helpers to make complex branching more concise, readable, and type-safe.
It supports lazy evaluation, chainable if/else-if/else flows, value/predicate-based switch/case, nullish coalescing for zero-values and pointers, and error-aware selectors.
Module:
github.com/aminofox/tern
Go version: 1.20+ (1.22 recommended)
go get github.com/aminofox/tern-
Ternary Expressions
T(cond, thenVal, elseVal)— eagerTF(cond, thenFn, elseFn)— lazy (evaluates only the selected branch)
-
Chainable Conditions (fluent, lazy)
When/WhenFn→ElseIf/ElseIfFn→Else/ElseFn
-
Switch/Case Style Matching
- Match by value:
.Case(val, result),.CaseFn(val, func() R) - Match by predicate:
.CaseWhen(pred, result),.CaseWhenFn(pred, func() R) - Fallback:
.Default(def),.DefaultFn(func() R)
- Match by value:
-
Nullish / Coalesce Helpers
FirstNonZero(vals...)— first non-zero-value elementOrElse,OrElseFn— zero-value fallback (lazy and eager versions)PtrOr,PtrOrFn— pointer fallback (lazy and eager)PtrCoalesce(vals...)— first non-nil pointer
-
Error-Aware Helpers
IfErr(val, err, fallback)— fallback on errorIfErrFn(val, err, func(error) T)— lazy fallback on errorChoose(producers...)— runs multiple producers until one returns(val, true)
import (
"fmt"
"strings"
"github.com/aminofox/tern"
)
// Ternary with nested conditions (lazy)
res := tern.TF[string](
len(items) > 0,
func() string { return strings.Join(items, ", ") },
func() string {
s := strings.TrimSpace(maybe)
return tern.T[string](s != "", s, "N/A")
},
)
fmt.Println(res) // "apple, banana"
// Chain if/else-if/else
grade := tern.When[string](score >= 90, "A").
ElseIf(score >= 80, "B").
ElseIf(score >= 70, "C").
Else("D")
// Switch/case with predicate
perm := tern.Match[string, int](role).
Case("root", 4).
Case("admin", 3).
CaseWhen(func(r string) bool { return strings.HasPrefix(r, "mod") }, 2).
Default(1)
// Nullish coalescing
name := tern.PtrOr(user.Nickname, "Guest")
limit := tern.OrElse(req.Limit, 50)
first, _ := tern.FirstNonZero("", "abc", "xyz")
// Error-aware fallback
data, err := service.Load()
out := tern.IfErrFn(data, err, func(e error) string { return "cached" })Run the full test suite (includes Example... functions that also appear in GoDoc):
go test ./...Run the CLI example:
go run ./examples- All functions with the
Fnsuffix are lazy — only the selected branch is evaluated. FirstNonZeroworks based on the Go zero-value for the type.Matchshort-circuits on the first matching case.- Fully generic and type-safe (requires Go 1.18+).
MIT