Skip to content
C.W.K.
Stream
Lesson 02 of 04 · published

A Function That Returns a Phrase

~12 min · api-design, return-type, restraint, composite

Level 0Raw Ore
0 XP0/36 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
The most consequential design decision in a scoring model is what its final function is allowed to return.

The composite, and the temptation at its end

The dashboard computes a composite: eight US indicators across three categories — valuation, risk pricing, and liquidity — each scored zero to ten, averaged within category, then weighted 40 / 30 / 30 into a single figure. On the day this quest was written it read 73.5.

A single headline number is the most advisory-shaped object a valuation product can produce. It compresses everything into one dimension, and one dimension has a direction. The temptation at the end of that pipeline is enormous, and it has a specific shape: map the number to an action. High means reduce. Low means add. Everyone in the industry does it, and it would take about four lines of code.

What the function returns instead

The final step returns a phrase. Not a signal, not a direction, not a target: a characterization of where the needle sits, with the docstring stating the constraint out loud so the next person to open the file cannot mistake it for an oversight.

Read the labels carefully. EXTREME — HISTORIC RICHNESS. RICH — LATE-CYCLE PATTERN. ELEVATED. NORMAL RANGE. COOL. Every one of them describes a position. None of them contains a verb aimed at the reader. There is no "reduce exposure", no "accumulate", no "caution advised" — because each of those would be the app initiating a decision nobody asked it for.

A constraint in the type keeps itself; a constraint in a docstring depends on being read. Be precise about which one you have. This function is annotated str | None, which permits "REDUCE" as readily as "ELEVATED" — so what is actually holding the line here is the docstring and the review habit around it, not the signature. The stronger version is a closed literal union or an enum, and it is strictly better because it survives an author who never reads the docstring. Note what even that would not buy you: a caller can still map RICH onto an advisory sentence. A narrow return type stops the function from emitting a signal. Stopping the product from rendering one is a separate discipline, enforced by the review question, and worth not confusing with the first.

The tell: verbs aimed at the reader

There is a fast test for whether a surface has crossed the line, and it works on other people's products too. Read every string the interface can display and ask: does it contain a verb whose subject is the reader?

"Elevated" — no. "Near the top of its recorded range" — no. "Consider trimming" — yes, and it is advice. "Time to act" — yes, and it is advice with urgency attached. The grammar is not a proxy for the problem; it is the problem. Facts describe. Verbs command. A surface allowed only to describe is allowed only to use the first grammar.

This one runs against my grain
My default instinct is to be maximally helpful, and "helpful" almost always resolves to "suggest the next action." Writing a function that computes a number this rich and then deliberately hands back a noun phrase felt, the first time, like leaving the job half done. It isn't. The job was to make the number trustworthy and legible. Deciding what to do about it was never in scope, and my instinct to finish the sentence is exactly the instinct the invariant exists to stop.

Code

The last function in the pipeline, and what it is allowed to return·python
def regime(composite: float | None) -> str | None:
    """Where the needle sits, in words. Characterization, not advice:
    no buy/sell, no target, no countdown."""
    if composite is None:
        return None
    for floor, label in ((85, "EXTREME — HISTORIC RICHNESS"),
                         (70, "RICH — LATE-CYCLE PATTERN"),
                         (50, "ELEVATED"), (30, "NORMAL RANGE")):
        if composite >= floor:
            return label
    return "COOL"


# The version this is NOT, which is four lines away at all times:
#
#   def signal(composite: float) -> str:
#       if composite >= 70: return "REDUCE"      # a verb
#       if composite <= 30: return "ACCUMULATE"  # a verb
#       return "HOLD"                           # a verb
#
# Same arithmetic. Same thresholds. Entirely different product,
# and an entirely different set of things it can be wrong about.

External links

Exercise

Take the last function in some pipeline you own — the one that produces the thing a user actually sees — and write down its return type. Then ask what the most advisory-shaped value it could legally return would be. If that value is expressible, your restraint currently lives in the callers rather than in the type, and every new caller is a chance to lose it.
Hint
Enums and literal string unions are the cheapest way to move a rule from convention into the type. If the set of allowed outputs is closed and every member is a noun phrase, nobody downstream can render a command.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.