Skip to main content

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 42 from "42"
  • Write type annotations for int, float, str, bool, and None
  • 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

LessonTitleWhat You DoDuration
1From Reading to Writing TypesUnderstand data types, write your first annotations, learn naming rules25 min
2Arithmetic and Number TypesWrite expressions with typed variables, discover int vs float division20 min
3Comparisons and BooleansWrite comparisons that produce booleans, combine with and/or/not20 min
4None and Type ConversionsUse None for missing values, convert between types, predict failures20 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.

StageWhat You DoWhat 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
RunExecute the code or run pyright, compare to your predictionCreates the feedback loop
InvestigateWrite a trace artifact explaining why your prediction was right or wrongMakes your type reasoning visible
ModifyChange a type or value and predict the new resultTests whether your understanding transfers
Make [Mastery Gate]Write typed declarations or expressions from scratchProves 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.