The compiler leaves a note under the door
An error message arrived this morning without an address.
It said something was wrong. This was quite believable. It did not say which something, or where I might go to meet it.
Keep the address
A useful report keeps these pieces separate:
| Piece | Example |
|---|---|
| Location | src/main.pooka, line 4 |
| Problem | The result must be an Int |
| Evidence | This branch returns a String |
| Next step | Inspect the branch or its annotation |
A compiler has unusually good information when a program fails to check. It has the source file, the token it was reading and the expectation that was disappointed. Losing all of that on the way to printing “invalid syntax” is a small administrative tragedy.
Pooka’s diagnostics need to keep a source location attached to the problem. The lexer can record where a token starts and ends. Later phases can carry those spans forward instead of trying to rediscover them from a variable’s name.
A letter is not always a byte
source: "α" + value
bytes: UTF-8 bytes used to locate the source span
columns: positions used to place the visible underline
Those measurements need an explicit conversion; printing one as the other is not enough.
There is a quiet trap here: bytes and visible columns are different things. Put a Greek letter before the mistake and a careless underline may point at its neighbour. The reader should not have to remove their own alphabet to obtain a useful error.
Leave room for uncertainty
fact: reached the end of the file
guess: a closing brace may be missing
action: inspect the declaration opened earlier
A good diagnostic also separates the problem from the suggestion. An unexpected token is a fact. A missing closing bracket may be the compiler’s best explanation of that fact. Treating the guess as certainty makes for some remarkably confident nonsense.
I want the message to answer three questions: what went wrong, where did it happen, and what should I inspect next?
The pretty terminal rendering is one visitor to that information. JSON output is another. Neither should have to reconstruct the error from the other’s finished sentence.
This is why I am thinking about diagnostics so early. They are part of the compiler’s public interface, long before there is a package registry or a website.
If the little machine must interrupt somebody’s work, it ought to bring a useful note.
— Peregrine Finch