Chapter 47: Primitive Types and Expressions
James opens his SmartNotes project in the editor. He has a clean project from Chapter 44: uv, pyright, ruff, pytest, Git all configured and passing. He types word_count = 350 and moves on. Emma stops him.
"What type is that?"
James looks at the screen. "It's a number. Obviously."
"Obviously to you. Not to pyright. Not to the next developer who reads your code. And not to Claude Code when you ask it to write a function that uses word_count." She types four characters after the variable name: : int. The line becomes word_count: int = 350. "Now everyone knows, including the tools."
This is the shift from Phase 1 to Phase 2. In Chapter 45, you learned to read typed Python. You could look at age: int = 30 and know what it meant. Now you write it yourself. Every variable, every expression, every value gets a type, because types are the vocabulary you use to tell AI precisely what to build.
Why Types Matter for Specification
In Chapter 43, you learned Axiom V: Types Are Guardrails. In Chapter 44, you saw pyright catch errors. This chapter makes types your primary tool. When you write word_count: int = 350, you are not just labeling a variable. You are making a promise: "This value is an integer. Any function that uses it can rely on that fact. Pyright will enforce this promise even when I am not looking."
That promise becomes powerful in Chapter 49 when you write function signatures like def reading_time(word_count: int, wpm: int = 250) -> float. The types in that signature ARE the specification. AI reads them and knows exactly what to build.
What You Will Learn
By the end of this chapter, you will be able to:
- Explain what a data type is and why Python distinguishes
42from"42" - Write type annotations for
int,float,str,bool, andNone - Follow Python's variable naming conventions (snake_case, valid names, reserved words)
- Predict the result of arithmetic, comparison, and boolean expressions
- Convert between types using
int(),float(),str(),bool()and predict which conversions fail - Read pyright error messages and fix type mismatches
Chapter Lessons
| Lesson | Title | What You Do | Duration |
|---|---|---|---|
| 1 | From Reading to Writing Types | Understand data types, write your first annotations, learn naming rules | 25 min |
| 2 | Arithmetic and Number Types | Write expressions with typed variables, discover int vs float division | 20 min |
| 3 | Comparisons and Booleans | Write comparisons that produce booleans, combine with and/or/not | 20 min |
| 4 | None and Type Conversions | Use None for missing values, convert between types, predict failures | 20 min |
PRIMM-AI+ in This Chapter
Every lesson includes a PRIMM-AI+ Practice section following the five-stage cycle from Chapter 42. This is Phase 2: you are now WRITING type annotations, not just reading them.
| Stage | What You Do | What It Builds |
|---|---|---|
| Predict [AI-FREE] | Predict what pyright flags or what an expression evaluates to, with a confidence score (1-5) | Calibrates your type intuition |
| Run | Execute the code or run pyright, compare to your prediction | Creates the feedback loop |
| Investigate | Write a trace artifact explaining why your prediction was right or wrong | Makes your type reasoning visible |
| Modify | Change a type or value and predict the new result | Tests whether your understanding transfers |
| Make [Mastery Gate] | Write typed declarations or expressions from scratch | Proves you can specify types independently |
The SmartNotes Connection
At the end of this chapter, you will define typed variables for a SmartNotes note: title: str, word_count: int, reading_time: float, is_draft: bool. Then you will write a reading_time_minutes() function stub and let AI generate the body. This is your first taste of using types as specification vocabulary for a real project.