In the compiled signature of a handler declared over a restricted type placeholder, what type does that placeholder appear as?
answer
- it collapses to something concrete
- look at the restriction first
- unrestricted means the root type
- restricted means the limit itself
- declaration decides, call sites do not
basics
~10 sIt appears as its limit — the type the restriction named. An unrestricted placeholder appears instead as the platform's root reference type. The declaration alone decides the collapsed shape; call sites never influence it.
solid answer
~40 sIt collapses to its **limit**. A handler declared over a placeholder restricted to, say, a refundable-item supertype compiles to a handler whose parameter and return positions read as that supertype. Where the declaration restricts nothing, the placeholder collapses instead to the platform's **root reference type**, because no narrower type is guaranteed. Where the declaration names two limits at once, the executable shape carries one type for that position — commonly the first one named — while the other is enforced during compilation only. The decision is made entirely at the declaration: the arguments that call sites supplied were checked before the collapse and leave no trace in the compiled shape. Nested positions collapse too, so a parameter written as a list of the placeholder compiles to a list with no element description at all.
code
pseudocode · 11 lines// source, as written
function totalOf<T restricted to RefundableItem>(items: list of T) returns Money
// compiled shape an examiner finds
function totalOf(items: list) returns Money
// the parameter's element position is gone;
// a value of the placeholder reads as RefundableItem
// same function with no restriction
function totalOf<T>(items: list of T) returns Money
// compiled: a value of the placeholder reads as RootTypego deeper
The thing to hold onto: a restricted placeholder becomes the type it was restricted to, and an unrestricted one becomes the most general reference type there is.
Be able to walk a declaration through the collapse position by position, including a nested one, and to say why the limit and not the arguments decides the outcome.
Demonstrate the reading habit: from a collapsed signature, predict how much the artifact still promises a caller and where conversions had to be inserted.
The trade to own is how much a published signature still says about itself after the build, and whether your teams write restrictions for the body's benefit only or for the artifact's readability too.
## What "collapse" means When a platform discards type arguments, it does not remove the placeholder and leave a hole where it stood. Every position that mentioned the placeholder is rewritten to a concrete type: the placeholder **collapses** to one shape that the executable signature then uses everywhere. The interesting question is which shape, and the answer comes from the declaration and nowhere else. ## The rule, in two cases - **Restricted placeholder.** The restriction tells the compiler what is true of every possible argument — every one of them is at least the limit. That is also the strongest thing the executable signature can honestly say, so the placeholder collapses to **the limit**. - **Unrestricted placeholder.** Nothing is guaranteed beyond "it is some reference value", so the placeholder collapses to the **platform's root reference type**. The restriction therefore does double duty. During compilation it decides what the body is allowed to call on a value of the placeholder. After compilation it decides what the signature reads as. | Declared form of the position | Shape in the compiled signature | |---|---| | Unrestricted placeholder | The platform's root reference type | | Placeholder restricted to one limit | That limit | | Placeholder restricted to two limits | One of them — commonly the first named | | Placeholder restricted to another placeholder | Whatever that chain finally resolves to | | A list of the placeholder | A list, with no element description | ## Nested positions collapse as well The last row is the one people forget. A parameter written as *a batch of the placeholder* does not become *a batch of the limit* in any observable sense — the element description of the batch is itself a type argument, and it is discarded on the same pass. What an examiner finds is a batch position with nothing said about its elements. ## What the collapse does not change 1. **What callers may pass.** Every call site was checked against the written declaration before anything collapsed. The collapse is a property of the emitted artifact, not a relaxation of the rules the source was compiled under. 2. **What the body does.** The body was type-checked against the placeholder's limit and behaves identically; the collapse renames the positions, it does not rewrite the logic. 3. **Safety inside checked code.** Nothing the compiler verified becomes uncertain because the signature now names a wider type. ## Why an examiner cares Reading the compiled artifact of an order pipeline, you see a handler whose parameter is the refundable-item supertype where the source said *placeholder restricted to refundable item*. Two things follow immediately. First, you now know exactly how much the erased signature can promise a caller — no more than the limit. Second, you know where the compiler had to insert conversions: at every caller that wanted the value back at a narrower type than the collapsed one. A signature that collapsed to the root reference type will have conversions at almost every use; one that collapsed to a tight limit may need very few. This is also the practical argument for writing a restriction even when the body barely needs one. A restriction is not only permission for the body to call something; it is the shape the compiled signature will carry, and therefore how much information the artifact still tells anyone reading it. ## Where candidates go wrong The most common wrong answer is that the placeholder collapses to something derived from the **arguments actually used** — the most specific common supertype of them, or a separate shape per call site. Both describe a different strategy: deriving a shape per argument is what a platform does when it generates a body per argument, which is the opposite of discarding the argument. On an erasing platform the compiled shape is fixed by the declaration before any call site is consulted, and adding a new call site with a new argument changes nothing about it. The second wrong answer is that two limits appear jointly in the executable shape. The compiled position holds a single type; the second limit's obligations were discharged during compilation, where the body was allowed to use members of both. ## Saying it in one breath "It collapses to its limit — to the root reference type if there is no limit — and that is decided by the declaration, not by anything a caller passed."
- A parameter is written as a batch of the placeholder — what does the compiled parameter position look like?A batch position with nothing said about its elements. The element description is itself a type argument and is discarded on the same pass, so the collapse does not turn it into a batch of the limit; it turns it into a batch, full stop.
- Does the collapse change which arguments a caller is allowed to supply?No. Call sites are checked against the declaration as written, before anything collapses, so the accepted set of arguments is unchanged. The collapse describes the shape of the emitted signature, not the rules the source was compiled under.
- If a placeholder is restricted to another placeholder, what shape does it collapse to?Whatever the chain finally resolves to. Follow the restrictions until one names a real type and use that; if the chain ends at an unrestricted placeholder, the position collapses to the root reference type, exactly as an unrestricted placeholder would.
saying these in an interview costs you the question
- Says an unrestricted placeholder compiles to the narrowest argument used
- Thinks the compiled shape is chosen separately at each call site
- Cannot say what a restriction does to the compiled signature
- Believes two limits both appear in the executable shape
- Assumes a nested argument survives when the outer one does not
- Says the collapse widens what callers are allowed to pass