Greppability is an underrated code metric
Greppability — how easily code can be found with simple text search tools like grep — is argued to be an underrated design constraint that strongly affects day‑to‑day maintenance and debugging. Commenters trade off between writing code that’s easy to grep (e.g. consistent naming across layers, avoiding dynamically constructed identifiers, keeping log messages and user‑facing strings intact) and practices that favor purity, DRYness, or idiomatic nesting, noting that too much indirection or metaprogramming quickly breaks searchability. Many point out that modern IDEs, language servers, and AST‑aware tools can mitigate these issues, but grep and ripgrep remain indispensable in large, legacy, multi‑language or remote codebases, so small concessions to greppability often pay off for future readers.
Line length, autoformatters, and readability
- Many dislike rigid 80‑column limits and autoformatters that wrap or reflow code “just because,” especially long strings and tabular structures where alignment reveals patterns.
- Others argue that autoformatters and consistent limits (80–120 chars) save huge amounts of time and eliminate style bikeshedding, as long as they avoid touching string literals.
- Tension: “format to please diff/linters” vs “format to preserve human symmetry and greppability.”
Greppability vs IDE/LSP tools
- One camp leans heavily on IDE/LSP features (go‑to‑definition, find usages, call graphs) and sees raw grep as crude and noisy.
- Another emphasizes grep/ripgrep as universal, fast, and available on remote or constrained systems, especially for unfamiliar or legacy code, multi‑language trees, configs, and logs.
- Several note that syntax‑aware tools break down with preprocessor abuse, dynamic languages, metaprogramming, huge monorepos, or when tooling can’t be installed.
- Common conclusion: use both; write code so that both text search and semantic tools work well.
Naming, consistency, and cross‑layer alignment
- Many endorse “same name across layers” (DB column, JSON key, field, UI label) to make grep and mental mapping trivial, even if it violates per‑layer naming conventions.
- Others prefer distinct names per domain (e.g., DB vs UI) to reduce overload and clarify boundaries, accepting more complex searches.
- Case and separator variants (camelCase vs snake_case vs kebab-case) are a recurring pain; some propose smarter “style‑insensitive” search tools instead of contorting code.
Strings, logs, and i18n
- Hard‑coded, fully spelled‑out log and error messages are seen as extremely valuable for grepping from logs back to code; dynamic string interpolation and concatenation often break this.
- Pluralization and localization are tricky; naive inline logic becomes complex in languages with rich plural rules, pushing people toward ICU‑style message formats or structured i18n systems.
- Some advocate flat, fully qualified i18n keys and log tags for greppability; critics worry about brittleness and typos without strong tooling.
Language and syntax design
- Languages that mark definitions with clear keywords (e.g.,
func,def,fn) are praised for greppability; C’s flexible declaration syntax, macros, and casts are seen as harder. - Certain language design choices (Go’s method receivers, Nim’s case/underscore insensitivity, JavaScript arrow functions, heavy use of macros in C/Lisp/Rust) can either help or hurt searchability, depending on conventions and tooling.
Dynamic code, metaprogramming, and DSLs
- Dynamically constructed identifiers, reflection, magic attribute access, or heavy macro use are repeatedly cited as “grep‑hostile” and hard to debug.
- Some see these as powerful and appropriate for DSLs, but emphasize that custom tooling or tags/indexers should accompany such designs.
Structured data and config
- Flat vs nested JSON/YAML: flat keys are easier to grep and to hand‑edit; nested structures better express hierarchy and are friendlier to tools like jq.
- Several recommend using specialized tools (e.g., JSON flatteners, syntax‑aware greps, tree‑sitter‑based search) rather than redesigning all data solely for plain grep.