skip to content

How would you set a codebase-wide standard for point-free style when half the team reads it fluently and half does not?

level: principalimportance: nice to knowfreq 24%

answer

  1. a style rule needs a check
  2. the readership decides, not the style
  3. mechanical criterion beats use judgement
  4. scope by who reads the file
  5. never mandate a repo-wide restyle

basics

~20 s

Write a rule that a reviewer can check on a diff rather than one that asks for judgement, scope it to where the code is read most, and leave existing code alone. A standard nobody can apply gets relitigated every review.

solid answer

~40 s

Start from the readership, not from the style. With a split team, any rule phrased as "prefer point-free where it is clearer" will be argued in every review, because "clearer" differs by reader. Make it mechanical instead: erase an argument only where the rewrite introduces no new function, and require every stage in a chain to be a named step rather than an anonymous one. Scope it — the helpers that many people read get the conservative rule; a specialised module maintained by two people can go further. Do not mandate a sweep of existing code: a large behaviour-free diff spends review attention it cannot repay. Then check whether it worked by what happens in review and onboarding, not by how many definitions lost their parameter.

go deeper

for a junior

Know that whether to erase an argument is a team convention, and that following the surrounding code is the right default until a rule exists.

for a middle

Be able to state a criterion a reviewer can apply to a diff, instead of appealing to which version looks cleaner to you.

for a senior

Show how you would scope the rule by readership and keep it out of existing code, and name the review cost a vague rule creates.

for a principal

Own the trade between the vocabulary you can assume and the cost to the slowest reader, and be willing to set a narrow standard that actually gets applied.

## Why this is a readership decision Point-free style has no runtime consequence worth arguing about. Its entire effect is on the people who read the code, which makes a split team the decisive fact rather than an inconvenience. Half the team resolves a chain of combinators as fast as a sentence; half stops and decodes. Any standard that ignores that asymmetry is really a standard about whose reading speed counts. The second decisive fact is that style rules are enforced in code review by people under time pressure. A rule that requires judgement gets argued, and an argued rule gets applied inconsistently, which is worse than either answer applied uniformly — the codebase ends up with both styles *and* the review cost. ## Make the rule checkable The practical move is to convert the judgement into something visible in a diff: 1. **Erase an argument only where the rewrite introduces no new function.** If the diff adds a combinator that routes a value, the parameter stays. This is readable off the change itself. 2. **Every stage in a chain is a named step.** No anonymous inline functions in a chain that claims to be point-free; if the steps are unnamed, nothing is named. 3. **Every boundary must be nameable.** A reviewer should be able to say what the value between two stages is. If nobody can, split the chain and name the seam. These three are not arbitrary. Each one targets a specific way the style fails, and each one can be answered yes or no without knowing the reviewer's fluency. ## Scope it rather than universalising it | Where the code lives | Rule to apply | Why | |---|---|---| | Widely-read shared helpers | The conservative rule, strictly | Read by everyone including new joiners; the slowest reader sets the cost | | A specialised module with a settled owner pair | Room to go further | The readership is small, known and fluent | | Glue at a system boundary | Prefer the pointed form | Read most often under incident pressure, where decoding is expensive | | Test code | Pointed, almost always | The point of a test is to be read literally, not compressed | This is the part most teams skip, and it is where most of the value is. A single universal rule has to be set at the level of the least fluent reader of the most-read file, which makes it needlessly conservative everywhere else. ## Do not mandate a migration The reflex after agreeing a standard is to apply it to everything. Resist it. A repo-wide restyling produces a large diff that changes no behaviour, and review attention is the scarcest resource on the team: spending it on a change that cannot introduce a bug it could also catch is a poor trade, and a diff that large is reviewed by scrolling. Apply the standard to new code and to definitions you are already editing for another reason. The codebase converges on the working set, which is the part being read anyway. ## What to do about the fluency split itself The standard is a stopgap for a knowledge gap, and it is worth saying so out loud. Two things actually close it: a short written page giving the vocabulary and the three rules with examples from your own code, and the habit of writing the pointed form in the review comment when asking for a change, so the reader sees the two side by side. Neither is a mandate. What does not work is assuming a style guide transmits fluency; people learn the vocabulary from code they had a reason to read. ## How you know it worked Count the right things. The wrong metric is how many definitions lost their parameter — that measures compliance, not benefit. The signals worth watching are whether style comments on this subject drop out of review, whether new joiners raise questions about specific chains, and whether the incident-time reading of boundary code got faster or slower. If the arguments keep happening, the rule was not checkable enough; if a specific module keeps generating questions, the scope was wrong there, not the rule. And it is a legitimate outcome to conclude that the answer for your team is "pointed by default, argument erased only where the rewrite adds nothing" and to stop there — a narrow standard that is actually applied beats a sophisticated one that is negotiated weekly.

  • Why is a rule phrased as "prefer point-free where it improves readability" worse than no rule at all?
    Because it delegates the disagreement to every review instead of settling it once. Readability differs by reader, so the rule gives both sides a citation and neither a decision. The result is inconsistent application plus a recurring review cost, which is worse than picking either style and applying it uniformly.
  • The standard has been agreed. What do you do about the thousands of existing definitions?
    Leave them. A repo-wide restyle is a large diff with no behaviour change, and review attention spent there cannot catch a bug because none can be introduced by intent. Apply the standard to new code and to definitions already being edited for another reason, so the codebase converges on exactly the part that is being read.
  • What would tell you the standard is set at the wrong level rather than simply being ignored?
    The pattern of the friction. Arguments spread evenly across reviews mean the rule is not checkable and needs to be more mechanical. Friction concentrated in one module usually means the scope is wrong there — a fluent owner pair is being held to the shared-helper rule, or a widely-read file was scoped as specialised.

saying these in an interview costs you the question

  • Argues from elegance rather than from who reads the code
  • Mandates a repo-wide rewrite to the new style
  • Writes the rule as use judgement with no checkable criterion
  • Assumes a style guide transmits fluency to the team
  • Applies one universal rule to shared helpers and specialised modules alike
  • Measures success by how many definitions lost a parameter