Forty columns each declare the same one-argument-to-text formatter shape inline — what does giving that shape one name buy you?
answer
- one shape, forty copies
- a name for the contract
- one place to change the shape
- shape matching versus name matching
- naming adds no extra checking
basics
~20 sNaming a recurring function type gives the contract one place to be read and changed, and reviewers a word for it. Where types match by shape it changes no compatibility; where they match by name, the name becomes the type.
solid answer
~40 sIt buys three things, none of them extra checking. **One place to read the contract**: a reviewer looks up `CellFormatter` instead of reconstructing the same shape from forty declarations. **One place to change it**: when the hook gains an argument, the shape moves once and every mismatch is reported against that one name. **A word for it**: the shape becomes a noun the team uses in review and in error messages. What it does not buy depends on how the language matches function types — where matching is by shape, the name is a readability device and any function of that shape still fits; where matching is by declared name, the name *is* the type and only values declared against it fit.
code
pseudocode · 10 lines// before: the same shape spelled out at every column
column.amount.formatter = function(value) -> text
column.opened.formatter = function(value) -> text
// ... thirty-eight more
// after: the shape is declared once, under a name
type CellFormatter = function(value) -> text
column.amount.formatter = CellFormatter
column.opened.formatter = CellFormattergo deeper
Recognise that a repeated function shape can be given a name, and that the name stands for the same in-and-out contract the columns were spelling out.
Explain what a name changes — where the contract is written and read — and what it does not change, which is what the checker enforces.
Argue it as a maintenance decision: when the contract changes, how many sites move and will every stale implementation be reported?
Decide whether a published shape deserves a name at all. A name is a commitment that the roles sharing it will evolve together, and that commitment is harder to undo than to make.
The renderer's columns all take a function of the same shape — one cell value in, display text out — and today that shape is spelled out at each of the forty registration sites. The question is what changes when the shape is declared once under a name, say `CellFormatter`, and the columns refer to the name. ## The same shape, spelled forty times A repeated inline shape is not wrong; it is just unnamed. The cost of leaving it unnamed shows up in three places. A reader has to reconstruct the contract from an example rather than look it up. A reviewer comparing two columns has to diff two shapes character by character to see whether they agree. And when the contract has to change, the edit is forty edits, with no single point that says what the contract is. ## What the name buys - **A single point of truth.** The shape is written once, and every column that refers to it is by construction in agreement with the others. - **A single point of change.** When the hook must pass more, or accept a different result, the declaration moves once and the checker reports every implementation that no longer matches, against one name. - **Vocabulary.** "This is a `CellFormatter`" is a sentence a team can use in review, in a commit message and in an error message. An anonymous shape gives nobody anything to say. - **Intent beyond the parts.** The shape says *one value in, text out*. The name can say *this is how a cell is rendered*, which is the part the shape cannot carry. ## What the name does not buy This is where candidates overreach. Naming a shape adds no checking that was not already there: - It does not make the argument count more strictly enforced — arity was already part of the type. - It does not restrict which columns may share one formatter value, or force them to. - It does not create a runtime entity; in most designs the name disappears entirely once the program runs. - It does not document behaviour. A name over a shape says what role the function plays, never what any particular implementation does. ## Shape matching versus name matching The one substantive difference between language families is how a function value is judged to fit the slot. | | Matching by shape | Matching by declared name | |---|---|---| | What decides compatibility | arity and the types in each position | the name the value was declared against | | Effect of introducing a name | a readability device; compatibility is unchanged | the name becomes the type that is checked | | Two identical shapes, two names | interchangeable | distinct types; a wrapper is needed to cross | | Cost | a shape can be matched by accident | a shape cannot be matched by accident | Neither is better in the abstract. Matching by shape makes small functions maximally reusable and makes accidental conformance possible — a function that happens to take one value and return text fits a slot nobody intended it for. Matching by name makes conformance deliberate and makes bridging two identical shapes a small chore. Knowing which model you are in tells you whether the name you just introduced changed anything at all beyond the reading. ## When naming is the wrong move 1. **The shape appears once.** A name adds a hop for the reader and buys nothing. 2. **The name would say less than the shape.** A name like `Handler` over *takes an event, returns nothing* hides exactly the part a reader needed. If you cannot name the role, leave the shape visible. 3. **Two roles share one shape by coincidence.** A cell formatter and an error formatter may both be one-value-to-text today. Naming them with one name asserts that they will move together, which is a claim about the future, not about the shape. ## The reviewer's version of the question Asked about a real codebase, the useful form is: when this contract changes, how many places must change, and will the checker tell me all of them? A named shape makes the answer *one, and yes*. An inline shape repeated forty times makes it *forty, and only for the ones you remembered to touch*. That is the whole of the argument, and it is an argument about maintenance rather than about type safety.
- The hook must now pass the row as a second argument — how does the named shape change the cost of that edit?The declaration changes in one place, and every implementation that no longer matches is reported against that one name rather than against forty independent shapes. The work of updating the implementations is unchanged; the name buys a single point of truth and an error message that says which contract broke.
- When is naming the shape not worth it?When it appears once, or when the name would carry less information than the shape it hides. A name earns its place when it states the role — how a cell is rendered — rather than restating the parts. Two roles that share a shape by coincidence should keep two names or none.
saying these in an interview costs you the question
- Claims naming the shape makes the checker enforce more.
- Thinks the name forces every column to share one formatter value.
- Believes a named shape always creates a distinct, incompatible type.
- Cannot say what happens when the shape itself has to change.
- Treats the name as documentation only, then lets the copies drift.