ternary

package
v0.10.0 Latest Latest
Warning

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

Go to latest
Published: Jan 23, 2026 License: MIT Imports: 0 Imported by: 0

README

ternary: single-line conditionals

Go lacks ternary expressions. This package provides them.

A ternary expression evaluates a condition and returns one of two values—if/else as an expression rather than a statement.

If := ternary.If[string]
status := If(task.IsDone()).Then("complete").Else("pending")

Scales linearly in struct literals (1 line per field vs 4):

return Gizmo{
    sprocket: If(sprocket != "").Then(sprocket).Else("default"),
    thingy:   If(thingy != "").Then(thingy).Else("default"),
}

See pkg.go.dev for complete API documentation. For function naming patterns, see Naming Functions for Higher-Order Functions.

Quick Start

import "github.com/binaryphile/fluentfp/ternary"

// Basic usage
status := ternary.If[string](done).Then("complete").Else("pending")

// Factory alias for repeated use
If := ternary.If[string]
result := If(condition).Then(trueVal).Else(falseVal)

// Lazy evaluation (short-circuit expensive calls)
config := ternary.If[Config](useCache).Then(cached).ElseCall(loadFromDB)

Types

Ternary[R] builds a conditional expression returning type R:

If := ternary.If[string]
status := If(done).Then("complete").Else("pending")  // string

Create with If[R](condition), set values with .Then() and .Else().

API Reference

Function/Method Signature Purpose Example
If If[R](bool) Ternary[R] Create with condition ternary.If[string](done)
.Then .Then(R) Ternary[R] Value if true (eager) .Then("yes")
.ThenCall .ThenCall(func() R) Ternary[R] Value if true (lazy) .ThenCall(compute)
.Else .Else(R) R Value if false (eager) .Else("no")
.ElseCall .ElseCall(func() R) R Value if false (lazy) .ElseCall(loadDefault)

Eager vs Lazy Evaluation

Eager (.Then/.Else): Both values are evaluated before the condition is checked:

// Both getValue() and getDefault() are called
result := ternary.If[int](condition).Then(getValue()).Else(getDefault())

Lazy (.ThenCall/.ElseCall): Only the selected branch is evaluated:

// Only loadExpensive() is called if useCache is false
result := ternary.If[Data](useCache).Then(cached).ElseCall(loadExpensive)

Use lazy variants when:

  • One branch is expensive to compute
  • One branch has side effects you want to avoid
  • One branch may panic or error

Patterns

Status Strings
status := ternary.If[string](task.IsDone()).Then("complete").Else("in progress")
Default Values with Conditions
timeout := ternary.If[int](config.Timeout > 0).Then(config.Timeout).Else(30)
Factory Alias for Repeated Use

When using the same return type multiple times, alias the factory:

func FormatReport(items []Item) string {
    If := ternary.If[string]

    var lines []string
    for _, item := range items {
        lines = append(lines,
            If(item.IsUrgent()).Then("[!] ").Else("    ") + item.Name,
        )
    }
    return strings.Join(lines, "\n")
}
Struct Literal Fields
func NewGizmo(sprocket, thingy string) Gizmo {
    If := ternary.If[string]

    return Gizmo{
        sprocket: If(sprocket != "").Then(sprocket).Else("default"),
        thingy:   If(thingy != "").Then(thingy).Else("default"),
    }
}

When NOT to Use ternary

  • Complex conditions — If logic needs comments, use if/else for clarity
  • Side effects — Ternary is for expressions, not statements with effects
  • Deeply nestedIf(a).Then(If(b).Then(x).Else(y)).Else(z) is unreadable
  • Single use with simple types — For a one-off if/else returning a simple value, traditional Go may be clearer

Appendix: Why ternary?

Most languages have single-line conditionals: C-style condition ? a : b, Python's a if condition else b, or functional if-then-else expressions. Go omitted them to prevent abuse.

This package provides ternary expressions for cases where they improve readability—particularly struct literals with conditional fields. Traditional Go requires 4 lines per field (3 conditional + 1 assignment); ternary requires 1. A 12-field struct: 48+ lines vs 12.

See Also

For optional values with defaults, see option.

Documentation

Overview

Package ternary provides a fluent ternary type for Go.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Ternary

type Ternary[R any] struct {
	// contains filtered or unexported fields
}

Ternary is a fluent ternary that offers the methods Then and Else, meant to be called in order. e.g. Ternary[string]{condition: true}.Then("yes").Else("no") returns the string "yes". See the If factory for more eloquent construction.

func If

func If[R any](condition bool) Ternary[R]

If returns a fluent ternary that ultimately yields a return value of type R when the Else method is called. e.g. If[string](true).Then("yes").Else("no") returns the string "yes". Don't be tempted to put in a function call as an argument to Then or Else thinking it won't be called when the condition doesn't match, i.e. don't do this: If[string](true).Then("yes").Else(ExpensiveNo()). ExpensiveNo() was already evaluated before If had a chance to look at it. Instead, use the ThenCall and/or ElseCall methods that take functions as arguments: If[string](true).Then("yes").ElseCall(ExpensiveNo)

ternary.If can read better in your code if you assign it to a variable when instantiating with a concrete type, e.g. var If = ternary.If[string] in the package namespace. As another alternative, the package itself can be dot-imported to good effect sometimes.

func (Ternary[R]) Else

func (i Ternary[R]) Else(e R) R

Else returns the then value if condition is true, otherwise elseValue.

func (Ternary[R]) ElseCall

func (i Ternary[R]) ElseCall(elseFunc func() R) R

ElseCall returns the then value if condition is true, otherwise elseFunc().

func (Ternary[R]) Then

func (i Ternary[R]) Then(t R) Ternary[R]

Then assigns the value returned by Else or ElseCall when condition is true.

func (Ternary[R]) ThenCall

func (i Ternary[R]) ThenCall(thenFunc func() R) Ternary[R]

ThenCall assigns the value returned by Else or ElseCall when condition is true but defers execution.

Jump to

Keyboard shortcuts

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