A call graph represents program entities as connected nodes, with arrows showing which functions or procedures call which others. It turns code relationships into a visual map of abstraction layers. section 9.15 section 8.10
Use a call graph to:
- Spot functions that mix levels of abstraction by comparing the lengths of their outgoing arrows. section 8.5
- Inspect the whole system, a particular layer, or one function through global, layer, and function zoom levels. section 8.6
- Guide extraction of more general functions that clarify code, improve testing, and enable reuse. section 8.8
- Reason about where changing, test-critical, and reusable code belongs within the graph. section 9.15 section 9.16
A shopping-cart graph
An initial freeTieClip(cart) function combines a loop, array indexing, item construction, and cart updates. Its call graph exposes calls spanning different abstraction levels. Extracting isInCart(cart, name) produces a clearer graph in which freeTieClip calls functions at more similar levels of detail. section 8.5 section 8.8
function freeTieClip(cart) {
var hasTie = false
var hasTieClip = false;
for(var i = 0; i < cart.length; i++) {
var item = cart[i];
if(item.name === "tie") #1
hasTie = true;
if(item.name === "tie clip") #1
hasTieClip = true;
}
if(hasTie && !hasTieClip) {
var tieClip = make_item("tie clip", 0);
return add_item(cart, tieClip); #2
}
return cart;
}
Inspect the original cart implementation whose loop, array indexing, item creation, and update calls reveal mixed abstraction levels. section 8.5
