Skip to content

Type Ceremony ​

What fraction of your code is boilerplate rather than logic?

Ceremony ratio = ceremony lines / total lines. Ceremony lines are imports, package declarations, main wrappers, lone closing braces, and type-only annotation lines. Lower means more of your code does actual work.

Ceremony by Language ​

Averaged across 7 benchmark problems.

Language ↕Ceremony Ratio ↑Ceremony Lines ↕Total Lines ↕
Clojure★0▼★0▼★8▼
Erlang★0▼★0▼★12▼
Python★0.105▼★1.7▼★14.6▼
Elixir★0.147▼★2.6▼★17.4▼
Zig★0.195▼★7.1▼★39.9▼
Objective-C★0.214▼★3▼★14▼
Haskell★0.221▼★5▼★21.9▼
JavaScript★0.222▼★3.1▼★15.7▼
Ruby★0.224▼★3.1▼★14.3▼
TypeScript★0.229▼★3.4▼★15.9▼
Swift★0.27▼★6▼★22.3▼
Kotlin★0.284▼★5.9▼★19.7▼
Go★0.31▼★8.1▼★26.6▼
Milo★0.313▼★8.3▼★26.9▼
Rust★0.317▼★7.1▼★22.6▼
C★0.326▼★11.7▼★39.7▼
C++★0.348▼★9.6▼★27.9▼
Java★0.397▼★10.3▼★26.6▼
C#★0.438▼★7▼★16▼

What drives the differences? ​

Python (10%) — no imports for builtins, no main wrapper, no braces. Almost every line is logic.

Java (40%) — package declarations, class wrappers, public static void main, import statements, closing braces. Nearly half the code is scaffolding.

Rust (32%) vs Zig (20%) — Rust's use imports, fn main(), and match arm braces add up. Zig's @import is terser and comptime reduces boilerplate.

Go (31%) — package main, import, func main(), explicit if err != nil blocks. Error handling is ceremony by design — Go chose explicitness over conciseness.

TypeScript (23%) vs JavaScript (22%) — nearly identical. Type annotations don't count as ceremony since they carry semantic weight. The difference is mainly import style.

What counts as ceremony? ​

Lines classified as ceremony:

  • Imports/includes — import, require, use, #include
  • Package/module declarations — package main, module X
  • Entry point wrappers — public static void main, fn main()
  • Lone closing delimiters — }, end, )
  • Type-only lines — lines that exist solely for type annotations with no logic

Lines NOT counted as ceremony:

  • Function signatures (they define behavior)
  • Variable declarations with initialization
  • Type annotations inline with logic
  • Comments
The formal basis

Ore et al. (ASE 2018) coined "Type Annotation Burden" and found: developers average 136 seconds per correct annotation and get it right only 51% of the time.

Annotations are expensive. Our ceremony metric captures the broader category — all structural lines that exist for the compiler rather than for expressing intent.