Ch36 Discussion

Discussion Guide

Opening prompt (5 min). "You start a job Monday and are handed a 300,000-line Fortran climate code and a bug to fix by Friday. You cannot read it. What do you actually do first, second, third?" Let students propose; steer toward: README/build file → entry point → module map → follow the one name that matters. The goal is for them to feel that reading front-to-back is absurd before you give them the alternative.

Prompt 1 — roles and boundaries. Put an unfamiliar module's first 20 lines on the board (a use list and a couple of procedure signatures) and ask: which of the five roles is this, and how do you know from the dependencies and signatures alone, without reading the bodies? Draw out that a module's use list and its public interface usually reveal its role.

Prompt 2 — where state lives. Show example-02's two via_global() calls returning 1.00 then 2.00. Ask: "Why is this legal, and why is it a nightmare to debug in a 100k-line code?" Then: "When is global module state nonetheless the right choice?" (Shared read-mostly configuration; a timer.) Push them to articulate the trade: convenience of not threading an argument vs. the cost of a hidden, searchable input.

Prompt 3 — build configuration and trust. "Two labs run the same source and get results differing in the sixth decimal. Give three reasons rooted in the build configuration, and say what each lab should have recorded." (Different -O/-ffast-math; different compiler/version; different BLAS/LAPACK.) Connect to why journals increasingly ask for build environments.

Mini group activity (15–20 min) — "Reorganize and defend." In groups of 3–4, hand each group the flat six-file solver listing (kinds, timers, heat_types, heat_solver, heat_io, heat). Tasks: (1) sort the files into a src/+app/+test/ tree, labeling each file's role; (2) draw the module map as a graph and read off a valid compile order; (3) decide fpm or Make and write the three-line fpm.toml or the dependency section; (4) each group defends one choice they had to make (e.g., "why is timers a utility and not part of the solver?"). Debrief by collecting the module maps on the board — they should all be the same tree, which is itself the lesson: good architecture converges. Extension for fast groups: where would a new advection physics module go, and what recompiles when you add it? (Answer: src/physics/ or beside heat_solver; only modules that use it recompile.)

Exit question. "In one sentence: why can a maintainer be productive in a code they have read less than 2% of?" (They hold the architecture and query the rest — navigation, not reading.)