awesome-everything RU
↑ Back to the climb

Base CS from zero

Abstraction: code reading

Crux Read small code snippets — a counter object, a module's exports, a stale-state breach, and a stack-overflow leak — and pick what the abstraction actually exposes, hides, or fails to hide.
Your altitude — climbing toward senior
ZeroJuniorMiddleSenior
You are at middle altitude — in the sky
◷ 14 min

Abstraction is judged in the code, not the definition. Read each snippet, decide where the interface ends and the hidden implementation begins, and spot the moment the boundary holds — or breaks.

Goal

Practise the read a working programmer runs constantly: find the interface a caller depends on, find the implementation behind it, and tell whether the hiding actually holds under the code in front of you.

Snippet 1 — the counter bundle

const counter = {
  count: 0,                       // data field — the state
  increment() {                   // method field — an operation
    this.count = this.count + 1;
  },
  value(): number {               // method field — another operation
    return this.count;
  },
};

counter.increment();
counter.increment();
let n = counter.value();          // n becomes 2
Quiz

Which line is the only one that names a data field, and what does that tell you about the bundle's interface?

Snippet 2 — the module

// module: text-format
const TABLE = { /* ... */ };               // a lookup table
function pad(s: string): string { /* ... */ }
function trim(s: string): string { /* ... */ }
export function format(s: string): string {
  return pad(trim(s));                     // uses both helpers
}
// another module, importing the one above
import { format } from "./text-format";
format("  hi  ");        // ok
pad("x");                // ??? — pad was never exported
Quiz

The importing module calls pad('x') directly. What happens, and what is the module's public interface?

Snippet 3 — the breach

// module: bank
let balance = 100;                  // private — no export
export function deposit(n: number) { balance = balance + n; }
export function getBalance() { return balance; }
// caller — what it can and cannot do
import { deposit, getBalance } from "./bank";
deposit(50);                        // ok — uses the interface
balance = -999;                     // ??? — reaching past the interface
Quiz

The caller assigns balance = -999 to force the balance negative, bypassing deposit. Why does the module's design stop this from being a real risk?

Snippet 4 — the leak

function depth(n: number): number {
  return depth(n + 1);   // never stops — no base case
}

depth(0);   // RangeError: Maximum call stack size exceeded
Quiz

The function-call abstraction promises 'call it, it runs, it returns'. This code crashes naming the call stack. What did the unit call this, and what is the lesson?

Recap

Every snippet is the same read at a different scale. In the counter, the interface is the methods and count is hidden behind this. In the module, only the exported format crosses the boundary while pad, trim, and TABLE stay private. In the bank, a private balance cannot be reached from outside, so the module can guarantee its invariant — the boundary turns a hope into a rule. And in the runaway recursion, the finite call stack leaks through the call abstraction the moment the lower layer hits its limit. Find the interface, find the hidden implementation, and check whether the hiding holds.

Continue the climb ↑Abstraction: build a leak-proof-then-leaky module
shortcuts expand
search
K
prev piece
k
next piece
j
cycle tier
t
this menu
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.