Chapter 5 — Teaching Notes
One-line purpose. Convert students from element-at-a-time thinking to whole-array thinking, and plant the one performance idea — column-major order — that the entire back half of the book depends on.
Key ideas to emphasize
- An array is a single object you compute with. This is the threshold. Keep returning to
c = a + b: it is not shorthand for a loop, it is more information than a loop, which is exactly why it is fast. Students who leave still writingdo ifor every array operation have missed the chapter. - Column-major, first index inner. The single most valuable habit in the book. Draw the memory-layout diagram on the board; make them recite "first index varies fastest" and "inner loop over the first index." Everything in Part VII is a consequence. Do not let it become hand-waving — tie it to the cache line.
a * bis elementwise, not matmul. The most common array bug for newcomers (especially from MATLAB, where*is matrix multiply and.*is elementwise — the reverse convention). Say it explicitly and drill it.- One-based indexing. Not a triviality — it is the off-by-one that bites every C/Python transfer once. Better they make it in class than in a silent out-of-bounds read.
- Allocatable arrays clean up after themselves. Contrast with C
malloc/free. Automatic deallocation removes a whole class of leak; it is a genuine safety feature, not a convenience.
Misconceptions to preempt
- "Whole-array
c = a + bis just less typing." (No — it exposes structure the compiler vectorizes.) - "
A * Bmultiplies matrices." (Elementwise.matmulfor the matrix product.) - "Loop order doesn't matter; the answer is the same." (Same answer, up to ~10× speed — the point of §5.6.)
- "NumPy and Fortran store arrays the same way." (Opposite: row-major vs column-major — a real interop bug.)
- "The first element is index 0." (One-based by default in Fortran.)
- "I must track an array's size in a separate variable." (No —
size(a)always knows.)
A live demonstration (5–8 minutes)
On godbolt.org with gfortran: (1) compile c = a + b on arrays and point out the vectorized instructions;
(2) write the two loop orders of a 2D initialization and show the generated code differs; (3) if time, paste
a * b vs matmul(a, b) for a 2×2 and print both, letting students see the numbers diverge. Wordless proof
that array form and memory order change what the machine does — you are not teaching assembly, you are
teaching that these choices are not cosmetic.
Class-time budget (~75 min for this bigger chapter)
- 10 min: first-class arrays, rank/shape/extent, one-based indexing (§5.1).
- 15 min: sections — the superpower; the
10*i+jself-checking matrix (§5.2). - 15 min: whole-array ops + constructors; the threshold concept; the Python comparison (§5.3).
- 10 min: the intrinsics, esp.
matmulvs*, and the LAPACK foreshadow (§5.4). - 8 min: allocatable arrays and automatic deallocation (§5.5).
- 12 min: column-major with the memory diagram and the live demo — the centerpiece (§5.6).
- 5 min:
where/masks on real data (§5.7) and launch the checkpoint.
Prerequisites to review
Chapters 3 (kinds/dp, integer division) and 4 (do loops, where) — the spaced-review questions target
exactly these. Confirm students can still write a counted do loop and remember why 7/2 is 3; the
integer-division trap reappears the instant they compute sum(k)/size(k) on an integer array.
Connections
Back: Ch. 1 (arrays/no-aliasing — now made concrete), Ch. 3–4 (types/loops/where). Forward and heavy:
Ch. 6 (arrays into procedures via intent/assumed-shape), Ch. 9 (field_t bundles the array), Ch. 15
(NumPy column-major, f2py), Ch. 21 (LAPACK — the matmul payoff), Ch. 24 (the heat stencil made real),
Ch. 27/29 (column-major measured and optimized). This chapter is the hinge of Part I; almost every later
chapter cashes a check written here.