pointless

command module
v0.0.1 Latest Latest
Warning

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

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

README

pointless

A Go linter that suggests using value types instead of pointers for small structs.

The name is a pun: "pointer" + "less" = "pointless" (also meaning "unnecessary").

Installation

go install github.com/mickamy/pointless@latest

Usage

# Basic usage
pointless ./...

# Change threshold (default: 1024 bytes)
pointless -threshold 512 ./...

What It Detects

1. Function Return Types
// Warning: consider returning value instead of pointer
func GetUser() *User { ... }

// OK: may return nil
func FindUser(id int) *User {
    if notFound {
        return nil
    }
    return &user
}

// OK: struct is large (> 1024 bytes)
func GetData() *LargeData { ... }
2. Method Receivers
// Warning: consider using value receiver
func (u *User) FullName() string {
    return u.FirstName + " " + u.LastName  // read-only
}

// OK: mutates receiver
func (u *User) SetName(name string) {
    u.Name = name
}
3. Pointer Slices
// Warning: consider using []User instead of []*User
func GetUsers() []*User { ... }
users := make([]*User, 100)

// OK: uses nil as element
if users[i] == nil { ... }
Not Checked: Function Arguments
// Too difficult to determine intent
func (r *UserRepo) Update(u *User) error
func Process(u *User) error

Suppressing Warnings

// nolint:pointless
func GetUser() *User { ... }

// pointless:ignore
func GetUser() *User { ... }

// nolint
func GetUser() *User { ... }

Configuration

Create .pointless.yaml or .pointless.yml in your project root:

threshold: 1024  # bytes

exclude:
  - "*_test.go"
  - "vendor/**"

CI Integration

# .github/workflows/lint.yaml
jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-go@v5
        with:
          go-version: '1.24'

      - name: pointless
        run: |
          go install github.com/mickamy/pointless@latest
          pointless ./...

Why Prefer Value Types?

Memory Layout
[]User (value slice):
┌────────┬────────┬────────┬────────┐
│ User 0 │ User 1 │ User 2 │ User 3 │  ← contiguous memory
└────────┴────────┴────────┴────────┘

[]*User (pointer slice):
┌────┬────┬────┬────┐
│ *  │ *  │ *  │ *  │  ← pointer array
└─┬──┴─┬──┴─┬──┴─┬──┘
  │    │    │    │
  ▼    ▼    ▼    ▼
┌────┐┌────┐┌────┐┌────┐  ← scattered allocations
│User││User││User││User│
└────┘└────┘└────┘└────┘
Benefits of Value Types
  1. CPU cache efficiency - Contiguous memory improves spatial locality
  2. Fewer allocations - 1 allocation vs N+1 allocations
  3. Lower GC pressure - Fewer pointers to track
  4. Immutability - Prevents unintended mutations
Why 1024 Bytes as Default Threshold?
  • Go goroutine stacks start at 2KB and grow automatically
  • A struct with ~50 fields typically uses 400-800 bytes
  • Contiguous memory copies are efficiently handled by CPU (SIMD-optimized memcpy)
  • Pointer indirection can cause cache misses, which may be more expensive than copying
  • Slice/map fields only copy the header, not the underlying data

License

MIT

Documentation

Overview

Command pointless is a linter that suggests using value types instead of pointers.

Directories

Path Synopsis
internal
analyzer
Package analyzer provides a linter that suggests using value types instead of pointers when the struct is small enough and doesn't require pointer semantics.
Package analyzer provides a linter that suggests using value types instead of pointers when the struct is small enough and doesn't require pointer semantics.
config
Package config provides configuration file support for pointless.
Package config provides configuration file support for pointless.

Jump to

Keyboard shortcuts

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