Skip to content

Symbol Noise

How many special characters clutter each line of code?

"Symbol noise" (formally: sigil density) counts non-alphanumeric, non-whitespace characters per line. Think: & * < > :: -> => ? ! ; : { } [ ].

Why it matters

Every special character is a micro-decision for the reader: what does this symbol mean in this context? Languages that overload symbols (& means reference AND bitwise-AND AND pattern-binding in Rust) impose more cognitive work per character.

Results

Language Avg Symbols/Line Avg Unique Symbol Types
Csharp3.814
Go4.216
Ruby4.314
Swift4.315
Haskell4.415
Kotlin4.615
Milo4.916
Python4.912
C5.321
Clojure5.38
Java5.617
Elixir5.715
Javascript5.815
Rust5.917
Cpp6.219
Typescript6.217
Zig6.419
Objc6.619
Erlang6.717

The two dimensions of noise

Symbols per line (density) — how cluttered does each line look?

Unique symbol types (vocabulary) — how many different squiggles do you need to learn?

These don't always correlate. Haskell has low density (4.6/line) AND low vocabulary (14 types) — few symbols used sparsely. Elixir has high density (6.4/line) but moderate vocabulary (15 types) — a few symbols (|>, &) used heavily.

Why each language is noisy (or not)

Rust's noise is safety-related. The &, mut, Some(), unwrap(), lifetime annotations — they encode ownership and borrowing. Each symbol carries real semantic weight.

TypeScript's noise is syntactic. Generics (<number, number>), non-null assertion (!), optional chaining (?.) — these serve the type checker, not runtime behavior.

Elixir's noise is pipeline-driven. The |> operator, pattern matching ({:ok, val}), anonymous functions (&(&1 + 1)) — dense but consistent.

Go avoids symbols by using words. make() instead of {}, append() instead of .push(). Lower symbol density, but more lines of code.

Ruby minimizes both. Blocks (do |x| ... end), English-like methods (empty?, puts, each), implicit returns — code reads almost like prose.

Key insight

Cognitive load scales with symbol variety (how many different symbols to learn), not symbol frequency (how often they appear). Seeing &&& is fine if & always means one thing. Seeing & &mut &'a *const *mut is five concepts in similar-looking syntax — that's expensive.

What counts as a symbol?

Everything that isn't a letter, digit, or whitespace: + - * / % = == != < > <= >= && || ! ~ ^ & | ; : , . :: -> => .. ..= ? # @ ' " ( ) [ ] { } < >

We count both total symbols per line (density) and unique symbol types per program (vocabulary).