# How to Use cmp.Or in Go for Default Value Chains

> Learn how to use cmp.Or in Go to simplify default value chains and eliminate verbose conditional blocks for configuration fallbacks and optional parameters.

- Repository: [JetBrains/go-modern-guidelines](https://github.com/jetbrains/go-modern-guidelines)
- Tags: how-to-guide
- Published: 2026-08-30

---

**The `cmp.Or` function from `golang.org/x/exp/cmp` returns the first non-zero value from a list of arguments, eliminating verbose conditional blocks when implementing configuration fallbacks and optional parameter defaults.**

Managing configuration in Go often requires checking multiple sources—command-line flags, environment variables, and hard-coded defaults—before settling on a value. The **JetBrains/go-modern-guidelines** repository explicitly recommends using `cmp.Or` to streamline these default value chains into concise, readable expressions. This helper function evaluates arguments left-to-right and returns the first one that differs from its type's zero value.

## Understanding cmp.Or in Go

### Core Functionality

`cmp.Or` is a generic utility that accepts any number of comparable arguments and returns the first non-zero value. If all arguments represent their type's zero value—such as empty strings, zero integers, or nil pointers—the function returns the last argument.

According to the source at [`internal/guidelines/guidelines_test.go`](https://github.com/JetBrains/go-modern-guidelines/blob/main/internal/guidelines/guidelines_test.go) line 16, the official guideline states: "Use `cmp.Or` to pick the first non-zero value from a fallback chain." This recommendation appears in the test file that validates the CLI output descriptions for the guideline tool, confirming its status as a modern Go best practice.

### Comparison with Traditional Approaches

Without `cmp.Or`, developers typically write repetitive `if` statements to check each candidate:

```go
var mode string
if flagValue != "" {
    mode = flagValue
} else if envValue != "" {
    mode = envValue
} else {
    mode = defaultValue
}

```

The `cmp.Or` function collapses this pattern into a single expression while maintaining type safety through Go generics.

## Implementing Default Value Chains with cmp.Or

### String Configuration Fallbacks

When configuring application settings from multiple sources, `cmp.Or` evaluates possibilities in priority order. The following example demonstrates a typical three-tier fallback: command-line flag, environment variable, and hard-coded default:

```go
package main

import (
	"fmt"
	"golang.org/x/exp/cmp"
)

func main() {
	var (
		flagValue   string // empty because flag not set
		envValue    string = "prod"
		defaultValue       = "dev"
	)

	// Returns "prod" - the first non-zero string
	mode := cmp.Or(flagValue, envValue, defaultValue)
	fmt.Println("Selected mode:", mode)
}

```

### Numeric Priority Selection

The function works identically for numeric types, making it ideal for port selections, timeout configurations, and retry counts:

```go
var (
	override int // zero because not overridden
	envPort  int = 8080
	defPort      = 80
)

port := cmp.Or(override, envPort, defPort) // Returns 8080

```

### Pointer and Interface Defaults

For pointers, `cmp.Or` treats `nil` as the zero value, returning the first non-nil pointer. This behavior supports dependency injection and optional override patterns:

```go
var (
	ptrA *int // nil
	ptrB = new(int)
)
*ptrB = 42

selectedPtr := cmp.Or(ptrA, ptrB) // Returns ptrB pointing to 42
fmt.Println("Selected value:", *selectedPtr)

```

## Installation and Module Requirements

The `cmp.Or` function resides in the experimental extensions module. As referenced in the repository's `go.mod` file, you must add the dependency before use:

```bash
go get golang.org/x/exp/cmp

```

Then import the package in your Go files:

```go
import "golang.org/x/exp/cmp"

```

The [`internal/guidelines/guidelines.go`](https://github.com/JetBrains/go-modern-guidelines/blob/main/internal/guidelines/guidelines.go) file generates the CLI recommendations that include this dependency, indicating its acceptance in the modern Go ecosystem despite its experimental location outside the standard library.

## Summary

- **`cmp.Or`** provides a concise mechanism for default value chains by returning the first non-zero argument from a variadic list.
- The **JetBrains/go-modern-guidelines** explicitly recommends this pattern in [`internal/guidelines/guidelines_test.go`](https://github.com/JetBrains/go-modern-guidelines/blob/main/internal/guidelines/guidelines_test.go) for handling configuration fallbacks and optional parameters.
- It eliminates verbose `if/else` blocks when checking flags, environment variables, and hard-coded defaults in priority order.
- The function supports all comparable types, including strings, integers, and pointers, with nil treated as a zero value.
- Available through `golang.org/x/exp/cmp`, it requires adding the experimental module to your project's dependencies.

## Frequently Asked Questions

### What is the difference between cmp.Or and coalesce functions in other languages?

Unlike SQL-style COALESCE which specifically handles NULL, `cmp.Or` compares against the Go zero value for the given type. This includes empty strings, zero integers, and nil pointers, making it type-safe through Go generics while serving the same logical purpose of returning the first "meaningful" value in a sequence.

### Can cmp.Or be used with custom struct types?

Yes, provided the custom type is comparable and you can define what constitutes its zero value. However, for complex structs, you should use pointers where nil represents "unset," as `cmp.Or` performs a direct comparison against the type's zero value rather than invoking an `IsZero()` method.

### Is cmp.Or part of the Go standard library?

No, `cmp.Or` currently resides in `golang.org/x/exp/cmp`, the experimental extensions repository. The `go.mod` file in **JetBrains/go-modern-guidelines** tracks this dependency separately from standard library packages, though the guidelines suggest it as a modern best practice for default value chains.

### How does cmp.Or handle boolean values?

`cmp.Or` treats `false` as the zero value for booleans, meaning it will skip `false` arguments and return the first `true` value. If you need to distinguish between an unset boolean and an explicit `false`, use a pointer to bool (`*bool`) where `nil` represents unset and `false` represents explicitly disabled.