Two reviewers call opposite styles idiomatic for the same module in a language that supports both - how do you settle it?
answer
- idiomatic is local, not universal
- the word stops deciding once styles multiply
- inside a module, follow the neighbours
- write the region rule down once
- review and onboarding are the real bill
basics
~20 sCost settles it, not taste. Once a language supports several styles, idiomatic means what this codebase decided plus what the surrounding module already does, so the fix is a written rule naming which regions use which style.
solid answer
~50 sBoth reviewers are right about the language and wrong about the question. In a language with one dominant style, 'idiomatic' is a property of the language; once it supports three, the word carries no decision, so the argument cannot be resolved by appealing to it. Resolve it in two steps. Inside a module, **local consistency wins**: a reader holds one model per file, and a style island in the middle of a region costs more in switching than it gains in elegance. For the module as a whole, the team needs a **written rule about regions** - which parts of the system are stateful, which are value transformations, where the boundary sits - so the debate happens once rather than in every review. What you are really arbitrating is review and onboarding cost, and that argues for fewer, larger, clearly labelled regions.
go deeper
Recall that inside an existing file the safe default is to match the code around you, and that 'idiomatic' stops being a decisive argument once a language supports several styles equally well.
Explain the two levels: local consistency inside a region, and a written rule about regions across the codebase. Be able to say why the switching cost falls on readers rather than on the author.
Show how you take the style question out of the review, merge on the consistency default, and reopen the region question separately with its cost named. Say what you would write down so the argument stays settled.
Own the convention across teams: how many regions the codebase can afford, how a region's style is changed, and the explicit trade-off between fit for each problem and the review and onboarding cost of every additional model in play.
## What the word stops meaning When a language has one dominant style, calling code 'idiomatic' is a real argument: it points at what the standard library, the tutorials and most of the ecosystem do, and following it lowers the cost for everyone who reads the code. When the same language supports three styles comfortably, the word no longer identifies one target. Both reviewers can cite genuine precedent, which is exactly why the argument loops. The first move is to notice that the disagreement is not about facts, and stop trying to win it with more precedent. ## The two levels the answer has **Inside a module, local consistency usually wins.** A reader keeps one model in their head while reading a region: what can change, where state lives, how errors travel. A file that switches models halfway makes them reload. That switching cost is paid by every reader forever, while the elegance of the better-fitting style is enjoyed mostly by the author once. So the default inside an existing region is: follow the neighbours. **Across modules, the team needs a written rule.** The durable fix is not winning this review but removing the class of argument: a short document that says which kinds of region exist in this codebase, which style each uses, and where boundaries sit. Then a review comment becomes 'this file is in the transformation region, so state belongs on the other side of the boundary' - a checkable statement rather than a taste claim. ## What the rule should actually say - **Name the regions and their styles**, in terms of the problem - the part with identity and lifecycle, the part that transforms values, the part that describes policy. - **Say where the boundaries are** and who owns the conversion at each one. - **Set a minimum size** for a region to have its own style, so nobody creates a three-function island. - **Say what happens to new code** that does not fit any region - who decides, and how the rule gets amended. - **Keep it short enough to be read.** A rule nobody reads is worse than no rule, because it gets cited selectively. ## The cost being argued about | Cost | Who pays it | What drives it | |---|---|---| | Review time | Every reviewer, every change | The number of conventions in play and how hard it is to know which applies | | Onboarding | Every newcomer, once but heavily | The number of models to learn plus whether the map is written down | | Switching while reading | Every reader of a mixed file | Style changes per file, not per repository | | Conversion code | The team that owns the boundary | The number of boundaries, not which styles they separate | The table is the argument. None of those costs is lowered by choosing the 'better' style; all of them are lowered by having fewer, larger, labelled regions. That is why a written rule beats a strong opinion even when the opinion is correct. ## Handling the review itself 1. **Separate the two questions**: is this change consistent with its region, and is the region's style right? The first is a review comment; the second is not, and should be taken out of the review. 2. **Apply the default** - consistency with the surrounding region - so the change can merge today. 3. **Open the real question separately**, with the region boundary as its subject, and time-box it. If the region's style genuinely should change, that is a migration with a cost, not a review note. 4. **Write down whatever you decide**, even if the decision is 'this region stays as it is'. An undocumented decision gets re-argued by the next pair of reviewers. ## Failure modes - **Deciding by seniority or volume.** It settles today's review and guarantees the same argument next month. - **Deciding per review.** The codebase accumulates a style distribution that matches the roster of reviewers rather than the shape of the problems. - **Mandating one style everywhere** to end the argument. It ends the argument and forces every problem into one shape, which is how you get objects with no behaviour and pipelines pretending they hold no state. - **Treating style as purely subjective** and refusing to rule. The cost is real and lands on readers, so declining to decide is itself a decision to pay it. - **Writing a rule that lists language constructs** instead of regions. Constructs go stale and invite lawyering; regions describe the problem and survive. The judgement being tested is whether you can convert a taste argument into a cost argument, decide it at the right level, and write the decision down so it stays decided.
- What belongs in the rule, and what should stay out of it?In: the regions the codebase has, the style each uses, where the boundaries sit and who owns the conversions, plus a minimum region size. Out: lists of individual constructs to prefer or avoid, which go stale, invite rules-lawyering in review, and describe the language rather than the problem the region solves.
- A genuinely better-fitting style is proposed for one file inside a region - do you allow it?Not as a one-file exception. Either the region is wrong and should change as a whole, which is a migration with a cost and a boundary, or the file follows its neighbours. Single-file exceptions are how a mixed repository forms, and each one is paid by every later reader of that region.
saying these in an interview costs you the question
- Settles it by seniority or by who argues longest
- Claims one style is objectively idiomatic in a language supporting several
- Grants one-file exceptions because the fit is better there
- Says style is subjective, so no decision is needed
- Writes a standard that lists constructs instead of naming regions