The Computing Series

The Concept

A module is a unit of code with a defined boundary: a public interface through which other modules interact with it, and private internals that no other module can see or depend on. Modules exist at every scale — a function, a class, a package, a service. The principle is the same at each scale: hide what can change, expose what must be stable.

The import graph makes the module structure visible. Every import statement is a directed edge from the importing module to the imported module. Cycles in the import graph are architectural problems: if module A imports B and B imports A, neither can be understood, tested, or deployed independently. The cycle has created a single entangled unit masquerading as two.

Connascence is a vocabulary for measuring the degree of coupling between modules. Two components are connascent if a change in one requires a change in the other. The types, ordered from weakest to strongest:

Connascence of Name — two components agree on an identifier. Module B calls module_a.process(). If A renames process, B breaks. This is the weakest form — renaming is mechanical.

Connascence of Type — two components agree on the type of a value. A passes an integer; B expects an integer. Changing to a float breaks the contract.

Connascence of Meaning — two components agree on what a value means. A passes status = 1 to mean “active”. B treats status = 1 as “pending”. This coupling is invisible to the type system and can be silent for months.

Connascence of Position — two components agree on the order of values. process(user_id, account_id) vs process(account_id, user_id) — positional connascence produces silent bugs when arguments are transposed.

Connascence of Execution — two components agree on the order of operations. initialize() must be called before process(). Violating the order causes runtime failures, not compile-time errors.

Connascence of Timing — two components depend on relative timing. Service A must write before Service B reads. This is the hardest to detect and the most expensive to violate.

The progression from weak to strong corresponds to increasing cost of change. Connascence of Name is tolerable and addressable with refactoring tools. Connascence of Timing is a distributed systems problem.

Read in the book →