Parameters & Arity Analysis¶
These describe the shape of a function’s parameter interface.
What it Measures¶
- Total parameters per
def- sum of all params across all parameter lists. - Parameter lists (curried arity) - how many (...) groups.
- Defaulted params - params with a default value (= ... in the declaration).
- By-name params - params typed as =>
T(lazy/only evaluated when used). - Context params (
implicit/using) - params that are implicit (Scala 2) or using (Scala 3). - Varargs (repeated) params -
A*. - Per-list classification - which lists are context lists.
How it's Measured¶
- From the function signature:
- Counts
(...)groups → parameter lists. - Within each group, counts parameters per list.
- Detects
implicit(Scala 2) /using(Scala 3).
- Counts
Why it Helps¶
- Large arity signals unclear responsibilities or missing domain objects.
- API ergonomics: High total parameter counts or many lists are friction at call sites.
- Readability & discoverability: Widespread implicit/using can be powerful, but too many context params harm discoverability; the metric makes it visible.
- Binary/behavioral stability: Defaulted params change call-site behavior (and can affect overload resolution). Tracking them helps avoid surprising changes.
- Performance semantics: By-name and varargs have runtime overhead/tradeoffs. Good to use sparingly, especially in performance-sensitive libraries.
- Refactoring targets: Surfacing the “top N highest-arity” defs is a great way to find APIs that should be split or redesigned.
Parameter Analysis: API Ergonomics¶
Parameters determine how pleasant a function is to call. Context parameters (using/implicits) can remove
boilerplate, but they also couple call sites to ambient scope. Defaults help discoverability, but they can hide
important choices. Strive for a small, explicit surface that reads like prose.
1. From implicit surprise to explicit context¶
using makes the dependency visible at the call site while remaining concise. Prefer local given instances to avoid
global, surprising resolution. Tests can supply alternate contexts explicitly.
Note
Name contexts (Format, Clock, Logger) clearly; keep them few and well-scoped.
2. Defaults and varargs¶
Replacing string type parameters with small enums removes spelling mistakes and enables exhaustiveness in callers’ matches. Defaults still help ergonomics, but the choice is explicit and discoverable.
3. Named arguments and builder alternatives¶
If a function has more than ~3 or 4 parameters, consider named arguments at call sites or move optional/rare options into a small config object with sensible defaults. This reduces positional mistakes and keeps signatures approachable.