Imperative programming organizes software as ordered instructions that change data or produce side effects. It emphasizes how execution flows toward a result rather than only describing the result. section 1.4.1
Common building blocks and design practices include:
- Loops for repeated actions, procedures for named instruction sequences, eager computations, mutable data structures, and pointers. section 1.4.1
- Modularity separates behavioral responsibilities, while opaque data types hide unstable implementations behind stable public interfaces. section 1.4.1
- Destructive updates, side effects, and risky type conversions can target low-level characteristics such as cache efficiency or reduced slow-memory access. section 1.4.1
Temperature monitoring scenario
A thermometer is read once per second. Conditional branches register normal readings, log measurements, and raise alarms when temperatures cross bounds; registration converts Celsius to Kelvin and stores the timestamp, value, and device. The same requirement can be reshaped as streams: one stream yields readings, while a monitor stores, validates, logs, alarms, and yields results. section 3.1.4 section 3.1.4
Listing 3.3 Temperature sensor readings scenario
Scenario: readThermometer #1
Description: monitor outside thermometer temperature
Given: outside thermometer @therm
Invocation: once a second
Read @therm, #2
Result: @reading(@time, @temp, @therm)
If @temp < -10C Then #3
register @reading #4
Log @reading #5
Raise alarm "Temperature is too low" #6
Else If @temp > 50C Then #7
register @reading
Log @reading
Raise alarm "Temperature is too high"
Else register @reading #8
Return @reading #9
Read the annotated scenario to trace invocation, branching, registration, logging, alarms, and return flow. section 3.1.4













