13.5 Functions: the signature is the contract
- Approved by
- Panaversity ·
In everyday life. A vending machine has a sign on its front: put in $2.00, get a drink. You press B4 for water and get orange juice. The sign's promise was kept, because you got a drink, but it was the wrong one, and you know it without opening the machine. Code is the same: try it with an answer you already know.
What you will learn. How to read the first line of a named piece of code as a promise, how to test it with one line you can check by hand, and why every number comes from a tested function.
Why it matters. A test shows a broken promise before you read the body, the code that does the work.
A function is a named piece of code that takes inputs and gives back a result.
What are the parts of a function?
Four, and the vending machine has all of them: a slot, the money you put in, the works inside, and the drink that drops out. This function adds a $25.00 fee to an amount in whole cents. Predict both lines.
function addFee(cents: number): number { // addFee takes an amount in cents
return cents + 2500; // and gives back the amount plus the fee
}
console.log(addFee(10000)); // put in 10000
console.log(addFee(60000)); // put in 60000Both print:
12500
62500| On the machine | In the code | Its name |
|---|---|---|
| The slot | cents | The parameter, the input the function takes |
| The money you put in | 10000 in addFee(10000) | The argument, the value you pass in |
| The works inside | The indented line | The body |
| The drink that drops out | What return gives back | The return value |
function starts a function in TypeScript, and def in Python. Each time the body ran, cents held the argument it was given.
What does a signature promise?
What you must give the function, and what you get back. The first line of a function, with its name, its parameters and their types, and its return type, is its signature. It is the sign on the machine. Here is one from Brightline: dueDate(invoiceDate: string, terms: string): string. Python writes the return type after an arrow: def due_date(invoice_date: str, terms: str) -> str:.
| Part of the signature | What it promises | In dueDate |
|---|---|---|
| Name | What the function is for | Works out a due date |
| Parameters with types | What you must give it | An invoice date as text, and the terms as text |
| Return type | What you get back | A due date as text, the last : string |
| What it does not say | Anything else must be in a test | That unknown terms are an error |
The sign promises the kind of answer, not the right answer. A return type of string accepts any text, as the machine's sign accepted orange juice. So only a test shows that the answer is right.
Why one job each?
A function that does one job can be named in a few words and tested on its own. A function that reads a file, computes due dates and prints a report is really three functions in one. When an agent writes a long function, ask it to split it, and then test each piece.
A function is pure when its result depends only on its inputs, and it changes nothing outside itself. dueDate("2026-10-07", "Net 30") gives the same answer every time, on any computer, so a test can check it.
Why must the math be done by a function, not a reply?
When you need a number, ask the agent to write the function and its tests, then run the function. Never accept a total, a date or a tax amount that a model worked out in its reply. It may look right and be wrong, and it may give a different total the next time. A pure function gives the same total every time. AI can reason about complex problems, but deterministic engines, which give the same output for the same input every time, should enforce accounting rules and mathematical consistency. A wrong rule still gives the same wrong answer every time. Confidence comes from rules you agreed, expected results you checked by hand, tests and review.
What is an assertion?
An assertion is a line that states what must be true, and stops the program with an error if it is not. It is the smallest possible test.
At work. Before Ana reads a new function's body, she says what its signature promises: "Given an invoice date and terms, it returns the due date." Then she picks one case she can check on a calendar, and the agent writes it as an assertion. An invoice on October 7 with Net 30 terms is due November 6. If the assertion passes, she reads the body. If it fails, she has found the bug without reading the body.
An assertion is the B4 press written down: you ask for something whose answer you already know, and see what drops out. Here the first assertion states the right day, and the second states a wrong one on purpose. An import line brings in code from a module, a file of ready-made code. Predict: which line prints, and what stops the program?
import assert from "node:assert/strict"; // bring in assert
import { dueDate } from "./src/due-date.ts"; // bring in the function to test
// October 7 with Net 30 must give November 6
assert.equal(dueDate("2026-10-07", "Net 30"), "2026-11-06");
console.log("first assert passed");
// the same call must give November 7: wrong on purpose
assert.equal(dueDate("2026-10-07", "Net 30"), "2026-11-07");
console.log("second assert passed");first assert passed
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
+ actual - expected
+ '2026-11-06'
- '2026-11-07'The second assertion expected the wrong day, and the program stopped.
Where the languages differ. assert.equal shows both values when it fails. In Python, assert is part of the language, and a plain assert shows only your message.
Try it
The file in 13-5 is addFee. Run it and investigate, as in 13.1.
Modify. Send: "Please change the fee in the file to $30.00, in whole cents. Don't run it yet." Work out both answers yourself. Then ask the agent to run it.
Make. Send: "Please add one assertion to the file: the fee on 10000 cents gives the answer I worked out, [your answer]. Run it." Then send: "Now change the answer in my assertion to one cent more, on purpose, and run it again."
What you should see. 13000 and 63000. The first assertion passes silently. The second stops the program with an AssertionError.
The operating rule: read a function's signature first and say its promise in one sentence, then test the promise with an assertion you can check by hand, before you read the body.

Figure 13.6. The signature is the contract. What goes in, what comes out, and the case you can check by hand.
Next. 13.6 shows how a program finds one value among many, and puts them in order.
Check yourself
Question 1 / 6
0 answered
The signature promises an int.def open_total(cents: list[int]) -> int:
total = 0
for c in cents:
total += c
print(open_total([210000, 34500]))What does it print?
- Owner
- Panaversity