Files
Rodin 65a433d0c6 chore: merge golang-conventions and prometheus-conventions into sources/
Absorbed content from rodin/golang-conventions and
rodin/prometheus-conventions into a sources/ directory.
Reference material — descriptive, not prescriptive.

Part of taxonomy cleanup (elixir-patterns issue #4).
2026-05-07 18:02:04 -07:00

271 lines
8.2 KiB
Markdown

# Go Language Source: Convention Reference
Quick-reference for conventions extracted from the golang/go source
code. Each entry: pattern name, location, example, when to use,
when NOT to use, origin.
---
## Owner-Attributed TODOs
**Location:** Throughout `src/`
```go
// TODO(gri): consider using a different approach here
// TODO(rsc): this should be cleaned up in the next release
```
**When to use:** Known limitations that a specific person should
address. The owner tag creates accountability without creating an
issue (issues are for user-visible problems; TODOs are for internal
engineering debt).
**When NOT to use:** User-visible bugs (file an issue instead).
Aspirational improvements with no clear owner. Anything that should
block a release.
**Origin:** Convention since Go's earliest commits. The Go team
averages 3,428 TODOs across the codebase — this is a conscious
engineering culture, not neglect.
---
## `internal/` Packages
**Location:** `src/internal/` (61 packages)
```go
// internal/singleflight — dedup concurrent calls
// internal/godebug — runtime feature flags
// internal/poll — OS I/O polling
// internal/bisect — binary search debugging
```
**When to use:** Code shared between stdlib packages that should NOT
become public API. Utility code that isn't stable enough for the
compatibility promise. Implementation details that users shouldn't
depend on.
**When NOT to use:** Code that external packages need. Code that's
stable enough for public API (promote it). One-off helpers that only
one package uses (keep them package-private).
**Origin:** `src/internal/` existed since Go moved sources from
`src/pkg` to `src` (2014). The compiler enforces the import restriction
— no code outside the tree can import internal packages.
---
## GODEBUG: Runtime Feature Flags
**Location:** `internal/godebug/godebug.go` (316 lines)
```go
var http2server = godebug.New("http2server")
func ServeConn(c net.Conn) {
if http2server.Value() == "0" {
// user opted out of HTTP/2
}
// IncNonDefault must be called each time non-default behavior fires
http2server.IncNonDefault()
}
```
**When to use:** Behavior changes that might break existing programs.
The old behavior becomes accessible via `GODEBUG=setting=value`. Tied
to `go.mod`'s `go` directive for automatic version-based defaults.
**When NOT to use:** Bug fixes that no reasonable program depends on.
New features (use GOEXPERIMENT instead). Performance optimizations that
don't change observable behavior.
**Origin:** Brad Fitzpatrick added the package in Aug 2021. Russ Cox
formalized it as the backward compatibility mechanism in proposal
#56986 (Nov 2022, 70 comments). 79 settings now exist.
---
## GOEXPERIMENT: Compile-Time Feature Gates
**Location:** `internal/goexperiment/flags.go` (136 lines)
```go
// Set via: GOEXPERIMENT=jsonv2 go build
// Check via build tag: //go:build goexperiment.jsonv2
```
**When to use:** Major new APIs or behavior changes that need real-world
testing before committing to the compatibility promise. The code lives
in-tree but isn't visible without the flag.
**When NOT to use:** Small features that can ship directly. Bug fixes.
Internal refactoring. Anything that doesn't need user feedback before
committing.
**Origin:** The GOEXPERIMENT mechanism predates its formalization — used
for fieldtrack, regabi, unified. json/v2 (Apr 2025) is the highest-
profile use: 6,387 lines shipped behind a flag.
---
## Compiler Directives
**Location:** Throughout `runtime/` and `cmd/`
```go
//go:linkname localName remote/pkg.ExportedName
//go:nosplit
//go:nowritebarrier
//go:noescape
//go:systemstack
```
**When to use:** ONLY in the runtime and compiler. `linkname` accesses
unexported symbols across packages. `nosplit` prevents stack growth
checks. `nowritebarrier` asserts no GC barriers. `systemstack` forces
execution on the system stack.
**When NOT to use:** In application code. In stdlib packages outside
runtime. In third-party packages (explicitly unsupported — the Go team
actively removes `go:linkname` targets that external packages depend
on).
**Origin:** 1,711 `go:linkname` and 2,428 other runtime directives.
The Go team is actively trying to reduce linkname usage (92 touches
in 2024, many removals).
---
## Generated Code (Checked In)
**Location:** `cmd/compile/internal/ssa/`
```go
// Code generated by ssa/gen/*.go; DO NOT EDIT.
// opGen.go — 97,135 lines
// rewriteAMD64.go — 79,703 lines
// rewritegeneric.go — 38,337 lines
```
**When to use:** When the generated output needs `git blame` history.
When generators should be auditable alongside their output. When build
reproducibility matters (no external tool dependency).
**When NOT to use:** When the generated output is large AND changes
frequently (diff noise). When the generator is trivial (just use
`go generate` at build time).
**Origin:** SSA compiler introduced on dev.ssa branch (2015). The
rewrite rules are generated from a DSL but checked in so reviewers
can see exactly what changed.
---
## Assembly in Runtime
**Location:** `runtime/*.s` (200 files)
```asm
// runtime/asm_amd64.s
TEXT runtime·gogo(SB), NOSPLIT, $0-8
MOVQ buf+0(FP), BX // gobuf
MOVQ gobuf_g(BX), DX
...
```
**When to use:** Context switches, atomic operations, system calls,
and anything that needs direct control over registers/stack. Each
architecture has its own set of assembly files.
**When NOT to use:** Anything that can be written in Go with acceptable
performance. The Go team actively converts assembly to Go where
possible (e.g., crypto packages moving from asm to Go+intrinsics).
**Origin:** Runtime has always included assembly — Go's scheduler and
GC require direct hardware control that no high-level language can
provide.
---
## Proposal Process (Committee Governance)
**Location:** GitHub issues, not PRs
```
Issue #71497 (json/v2): 201 comments, Jan 2025
Issue #56986 (GODEBUG): 70 comments, Nov 2022
Issue #56345 (slog): 841 comments, 10 months
Issue #15292 (generics): 874 comments, 5 years
```
**When to use:** Any user-visible API addition or behavior change.
The proposal process ensures all edge cases are considered before
committing to the compatibility promise.
**When NOT to use:** Internal refactoring, performance improvements
that don't change API, bug fixes. These go through normal code review
(Gerrit/GitHub).
**Origin:** The Go proposal process evolved from informal (early Go)
to formalized (2015+). Russ Cox and the Go team manage a proposal
review meeting that triages and decides.
---
## The Scheduler as Documentation
**Location:** `runtime/proc.go` (8,156 lines)
```go
// Goroutine scheduler
// The scheduler's job is to distribute ready-to-run goroutines over
// worker threads.
//
// The main concepts are:
// G - goroutine.
// M - worker thread, or machine.
// P - processor, a resource that is required to execute Go code.
```
**When to use:** Complex algorithms should document their model at the
top of the file. The Go runtime uses extensive comments to explain
the scheduler's invariants, the GC's phases, and the memory
allocator's structure.
**When NOT to use:** Simple code that's self-documenting. Comments
that restate what the code does rather than WHY it does it.
**Origin:** The G-M-P model comment dates to the scheduler rewrite
(2014). The convention of architectural documentation at file-top
extends throughout the runtime.
---
## json/v2: Experiment-to-Stdlib Pipeline
**Location:** `encoding/json/v2/` (6,387 lines, 13 files)
```go
// encoding/json/v2 — semantic layer (uses reflection)
// encoding/jsontext — syntactic layer (no reflection dependency)
```
**When to use:** When building a major stdlib revision. The pattern:
1. Build as external module (`go-json-experiment/json`)
2. Iterate with real users for years
3. Propose for stdlib with working implementation
4. Ship behind GOEXPERIMENT flag
5. Graduate when stable
**When NOT to use:** Small additions that don't need years of
iteration. Features that can be backward-compatible additions to
existing packages.
**Origin:** `go-json-experiment/json` existed since 2022. Proposed as
#71497 (Jan 2025, 201 comments). Landed behind flag Apr 2025 (commit
`0e17905793` by Damien Neil).
<!-- PATTERN_COMPLETE -->