A routine takes one value of an unknown type and returns a value of that same type — what can its body return?
answer
- the signature is the whole argument
- count what is reachable of that type
- nothing to inspect, nothing to construct
- the argument is the only material
- hand it back, or never return
basics
~20 sOnly the value it was handed. A body that can neither inspect nor construct a value of an unknown type has no other value of that type in scope, so the one body that returns a result returns its argument.
solid answer
~50 sRead the signature as a claim about every type at once: the caller supplies the type, the body is written once and is never told which type arrived, and it is handed no operation on that type. So it cannot build a fresh value of it, cannot produce a default for it, and cannot derive one from anything else in scope — every other value it can reach has a type the body names. The argument is the only material of that type available, so the one body that returns a result is the one that returns its argument. The caveats matter as much as the conclusion: the signature says nothing about whether the routine returns at all, nothing about effects along the way, and the whole argument assumes the body genuinely cannot ask what the type is.
code
pseudocode · 8 lines// signature: pick(value: T) -> T, for any T the caller chooses
function pick(value)
return value // the only value of type T in scope
// not available inside this body:
// make_new_T() nothing tells it how to build one
// default_of_T() the signature grants no default
// compare(value, x) no operation on T was handed overgo deeper
Recall the shape: one value in, the same type out, and no way to look at it or make another. The answer is that the argument comes back, and being able to say why is enough at this stage.
Explain the mechanics: enumerate what values of that type are reachable inside the body and show that the list has exactly one entry. Then state the caveats — termination and effects are not covered by the signature.
Show that you use this in review. Demonstrate how a narrow signature lets you approve a call site without reading the body, and name the conditions under which you would stop trusting it.
Frame the trade-off: narrowness bought by refusing to name a type is review capacity that scales across teams, paid for with call sites that must supply operations explicitly rather than assuming them.
## The claim a signature over an unnamed type makes A routine whose input is one value of a type it does not name — written below as the placeholder `T` — is not one routine per type. It is a **single body that must work for every `T` a caller can choose**. The caller does the choosing; the body was written and compiled before any choice existed, and nothing at run time tells it which choice arrived. **Parametricity** is the name for what follows: because the body cannot look at `T`, its behaviour cannot depend on `T`. That turns the signature from a label into a small proof, and the proof is what makes this an interview question rather than a definition. ## Counting the values of that type in scope The argument is mechanical. Standing inside the body, ask how many values of type `T` you can get hold of: - **The argument.** That is one. - **A freshly built value.** Not available — building one needs a constructor, a literal form or a representation, and the body has none of these for a type it does not name. - **A default, a zero, an empty.** Not available — "the default for `T`" is not something the signature hands over, and many types have no sensible one. - **A value read from elsewhere** — a field, a shared table, a collection. Anything reachable that way has a type the body *does* name, so it is not a `T`. - **A modified copy of the argument.** Modifying needs an operation on `T`, and the signature grants none. One value is reachable, and the result must have that type. Hence the body that returns a result returns its argument. ## What the proof does not cover This is where a careless statement of the rule fails, and interviewers listen for it: 1. **It does not prove the routine returns.** A body may loop forever, or fail. The type says nothing about termination. 2. **It does not prove nothing else happens.** Where effects are permitted anywhere, the body may write a log line, mutate something it reaches, or raise, and still honour the signature. 3. **It does not prove the type is opaque.** Some run times discard the type argument before execution; others keep it available and let the body ask what it was. Where the body can ask, it can branch on the answer, and the whole argument collapses. That is a property of the platform, not of the notation. Say the caveats out loud. A candidate who claims the signature proves "it always returns its argument, no exceptions" has over-claimed, and over-claiming is exactly what the question probes. ## The same argument at other shapes The reasoning is not special to one value in and one value out. It is a count of what the body can reach, and it scales: | Signature over an unnamed type `T` | Bodies that can return a result | |---|---| | one `T` in, one `T` out | exactly one — hand back the argument | | two `T`s in, one `T` out | exactly two — the first, or the second | | one `T` in, a list of `T` out | one per output length — the argument repeated *n* times, for any *n* at or above zero | | one `T` in, a number out | many — the result does not involve `T`, so the body is unconstrained | | one `T` in, nothing out | one observable behaviour — there is nothing to report | Every row assumes the same three conditions: the body is **total**, **effect-free**, and **cannot inspect** the type. Drop any one of them and the count in the right-hand column stops being an upper bound. ## Why this is worth an interviewer's time It separates two ways of reading a signature. One candidate reads it as documentation — a hint about intent that the body may or may not honour. The other reads it as a **constraint the compiler enforces**, and can therefore say what a call does without opening the body at all. The second reading is what makes uniform code cheap to review: a reviewer meeting an unfamiliar call site gets the answer from the declaration, and gets it for every type argument that will ever be supplied, including ones nobody has written yet. The practical habit that follows is to reach for an unnamed type **deliberately**, because the narrowness is the feature. A routine that names a concrete type has as many possible behaviours as its author had ideas; a routine over an unnamed type has, quite literally, one.
- What changes about that conclusion if the body is allowed to run effects before returning?The conclusion about the returned *value* survives — there is still only one value of that type in scope. What is lost is the claim that two calls are interchangeable: the body may log, mutate something it reaches, or fail partway, so replacing a call with its argument is no longer a safe rewrite even though the result would match.
- A routine takes one value of an unknown type and returns a list of that type — how many bodies now?One for each output length. Every entry in the result must be the single argument, so a body is fixed by how many copies it emits: none, one, two, and so on. The count is infinite but still tiny in shape — the body chooses a number, never a value.
- Does the argument still hold if the routine takes two values of the same unknown type?Yes, with the count raised from one to two. Both arguments have the required type, so a body may return either, but it has no way to choose between them based on what they are — it can only pick a position, and it picks the same position on every call.
A courier is handed one sealed, unlabelled parcel and told to hand back a parcel of the same kind, with nowhere to buy another and no way to open this one. The only parcel they can hand back is the one they are holding — though nothing stops them dawdling forever instead, which is why the rule promises a value, not a delivery.
saying these in an interview costs you the question
- Says the body could return a default value of that type
- Claims it can construct a fresh value of the unknown type
- Thinks the body may compare the value against something
- Says the signature proves the routine always returns
- Thinks the body is compiled once per type argument it meets