Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Solutions: 40 — Mechanism vs policy

Exercise 1 — Find the mechanism

systemmechanismpolicy
motionapply position + velocity updatenone (velocity comes from elsewhere)
food_spawnnonewhen and where food appears
next_eventcompute next collision/event time per creaturethe event categorisation rules
apply_eatapply consumption mechanicseats rule (collision detection)
apply_reproduceapply fission, split fuelreproduction threshold and offspring count
apply_starvemark for removalstarvation rule (energy <= 0)
cleanupapply mutationsnone (pure mechanism)
inspectread world statenone (pure mechanism for observation)

cleanup is the cleanest mechanism in the simulator: no decisions, just commits. inspect is the cleanest read-only mechanism. apply_starve and apply_reproduce are mostly policy with a thin mechanism layer.

Exercise 2 — Replace a policy

#![allow(unused)]
fn main() {
fn apply_starve(/* ... */) {
    for i in 0..energy.len() {
        if energy[i] < -10.0 && age[i] > 100 {  // changed from `<= 0.0`
            to_remove.push(ids[i]);
        }
    }
}
}

cleanup does not change. The simulator behaves differently; the kernel is unmoved. This is the test of separation: did the change touch only one file?

Exercise 3 — Add a new policy

#![allow(unused)]
fn main() {
fn apply_predation(/* ... */) {
    for i in 0..creatures.len() {
        if is_predated(creatures[i], world) {
            to_remove.push(ids[i]);
        }
    }
}
}

Both apply_starve and apply_predation push to to_remove. Cleanup applies the union without distinction. The two policies compose because they produce the same shape of output (an id to remove); the mechanism does not care why.

Exercise 4 — Anti-pattern

Common offender: a logger system that writes directly to disk inside the system body, rather than pushing to an output queue. It mixes “decide what to log” (policy) with “write to disk” (mechanism). Refactor the disk write into a queue + cleanup-style flush.

Exercise 5 — A second mechanism

A cleanup_with_archive mechanism reads to_remove and, instead of swap_remove-ing the row, copies it into a dead archive table before removing it from creatures. Policies (apply_starve, apply_predation) are unchanged — they still push to to_remove. Switch between the two mechanisms by swapping which one is in the DAG, not by editing any policy.