PrimitivesGENERALTEAM-SPECIFICILLUSTRATIVE

The Prerequisite Graph

A cart needs functions, conditionals and arrays; a map is an alternative to the array, not a prerequisite; objects are how an entry is shaped. Drawing what depends on what tells you which foundation to learn first and which ones the cart does not need at all.

The situation, the reflex, and why it stalls

Every lesson starts where being stuck starts: someone has a problem, and the first move that comes to mind feels like progress.

The question

You have found more than one gap on the walk down. Which do you fill first, which can wait, and which ones — despite appearing in every "learn to code" list — does this problem not need?

The situation

The walk down from the cart has produced a small pile of things you are unsure of: a loop, a function returning early, an object with two fields, maybe a map because the representation lesson mentioned one. It is not obvious where to start, and every list of "programming fundamentals" you find has forty items on it.

The reflex

Take the list in order. Variables, then types, then arrays, then objects, then functions, then classes — whatever order the reference book uses. It feels like laying foundations: nothing above can be built until everything below is done.

Why it stalls

The order is the book's, not the problem's. Classes are chapter nine and the cart does not use one; maps are chapter twelve and the cart chose an array. Weeks go into rungs the cart never stands on.

What the reflex produces — and fails to produce
  • The order is the book's, not the problem's. Classes are chapter nine and the cart does not use one; maps are chapter twelve and the cart chose an array. Weeks go into rungs the cart never stands on.
  • Nothing is testable until the end. A prerequisite studied in sequence has no cart to prove it in, so each one is "done" when the chapter is, and forgotten by the time the cart arrives.
  • The pile feels bigger than it is. Five small gaps, listed as a curriculum, look like a semester; drawn as a graph with the cart at the top, three of them turn out to be the same rung.
ProblemUnderstandRequirementsConstraintsUnknownsDecompositionSmallest StepModelExperimentObserveDebugLearnIterate

The move

Precisely enough to apply it to a problem you have never seen — not a slogan.

  • Draw the graph, not the list. Put the cart at the top. Under it, the operations. Under each operation, the pieces it is made of — and under those, the primitives, each drawn once even when several pieces need it. Edges point from the thing to what it needs. The concept record already holds this graph as primitives; the move is to read it as a plan.
  • Read upward from the bottom for the learning order. A node with no unfilled prerequisites can be learned now and tested now, because every node above it is waiting on it. For the cart the bottom layer is Variables → Arrays, Functions, Conditionals; then Objects (an entry is an object with two fields); then the operations; then the cart.
  • Read sideways for what is optional. Maps sit beside Arrays, not under them — a map is what you would choose instead of an array, and the V1 cart chose the array. It goes on the graph as an alternative with a dotted edge, and it goes on the learning list only when the representation question sends you there.
  • Read the edges for what to leave out. Classes, inheritance, async, generics: none of them has an edge into any cart operation. They are real fundamentals with no arrow into this problem, and the graph is permission to not learn them yet.

The graph, top down

The diagram is the concept's primitive graph drawn as it is meant to be read: the cart at the top, operations below, the pieces they are made of, and the primitives once each at the bottom. Two edges arrive at "loop" from different operations — that shared node is why the second operation is cheaper than the first. The map is beside the array with a dotted meaning: an alternative, not a prerequisite.

What the cart needs, drawn once each
or, when lookup must not scale with nShopping cartaddItemremoveItemtotalfind existing entryObjects — { productId, quantity }keep all but oneReturn earlyCompare idsLoop through a collectionFunctionsConditionalsArraysVariablesMaps (alternative)
UserLLMAgentToolDataDecisionHumanGuardrail

Reading the graph as a plan

Bottom-up gives the order; each step names the operation that proves it, because a primitive learned without a test above it is a chapter, not a rung. The alternative order — operation-first, learning each primitive at the moment an operation needs it — is the same graph read depth-first, and it suits a learner who needs to see the cart move to keep going.

Learning order for a learner missing loops and early return
  1. 1
    Loop through cart.items and print each productId

    because The lowest unmarked node; three operations wait on it, and it can be tested with two entries in a scratch file.

  2. 2
    Return early from inside the loop on the first match — findItem

    because The only other unmarked node, and it needs the loop to exist. Tested by findItem([Laptop × 1], "laptop") returning the entry.

  3. 3
    addItem, using findItem

    because Every node under it is now marked; the concept's first two examples prove it.

  4. 4
    removeItem and total

    because Their subtrees share the loop and comparison already built; nothing new is learned, which is the graph paying off.

  5. 5
    Map, only if a requirement asks

    because It is beside the array, not under the cart; the representation lesson decides when the dotted edge becomes solid.

a different valid order Operation-first: start at addItem, hit find-existing, learn the loop and the early return there, finish addItem, then move to removeItem and find nothing new to learn. Choose this when momentum matters more than tidiness — the same nodes get filled, in the order the operations demand them.

What is not on the graph

The most useful output of the graph is the list of things with no edge into it. Each row below is a genuine fundamental, appears early in most curricula, and has no arrow into any cart operation in V1. The "arrives with" column says which future requirement would draw the edge — so "not yet" has a condition, not a mood.

ConstructEdge into the V1 cart?Arrives with
Classes and methodsNo — the reference is five functions over a plain objectA cart with identity and behaviour worth binding together, or a codebase convention that says so
InheritanceNo — nothing is a special kind of cartPossibly never; composition covers a wishlist that shares operations with a cart
Async / promisesNo — every V0 operation is a pure in-memory stepV3: the API round trip and the database write
MapsDotted — an alternative to the array, not a prerequisiteA requirement that lookup must not scale with the cart, or that uniqueness be structural
GenericsNoA second concept sharing findItem's shape — find-by-id over any entry type

The implementation ladder

Concept, examples, pseudocode, code, tests, production — for the concept this lesson is about. Code is the fourth tab, not the first.

concept Shopping Cart beginner
Build it step by step →

Shopping Cart = A temporary collection of products the user intends to purchase, held between browsing and checkout.

Identity, ownership, lifetime
  • Does a cart have identity? Yes, weakly. Two carts with the same items are still two carts, because each belongs to someone and will become a different order. It needs an id once it leaves memory; in memory the variable is the identity.
  • Who owns it? A shopper — a logged-in user or an anonymous session. The owner is part of the state because "my cart" has to be findable again.
  • How long does it exist? From the first add until checkout or abandonment. Whether it survives a reload, a closed browser or a login is not a property of the concept; it is a persistence decision made later, and each answer changes where the cart lives.
  • Should it survive reload? Usually yes for a store, usually no for a demo. V1 in memory says no; V2 browser storage says yes on one device; V3 server storage says yes everywhere the user is logged in.
  • Should it survive login? Only if an anonymous cart and a logged-in cart are merged — a rule that does not exist in V1 and appears as a modification later.
State it must remember
  • itemscollection of CartItemkeepThe cart is its items; without them nothing else means anything.
  • items[].productIdidkeepThe reference to what is being bought. The catalog owns the product; the cart only points at it.
  • items[].quantityinteger > 0keepTwo laptops is one entry with quantity 2, not two entries — the rule "one entry per product" needs a quantity to hold.
  • owneruser id or session iddependsSo the cart can be found again by the person it belongs to.
  • items[].productNamestringderiveIt would be convenient to render the cart without a catalog lookup.
  • items[].pricemoneydependsThe total needs a price per item.
  • totalmoneydropEvery screen shows the total.
  • currencycodedependsPrices need a currency to be added.
  • createdAttimestampdropAbandoned carts might be expired or emailed about.
Operations
  • update Add item the updated cart
  • delete Remove item the updated cart
  • update Change quantity the updated cart
  • read View items the list of entries — product id and quantity — for rendering
  • domain Calculate total the sum of price × quantity over the entries
  • delete Clear cart the empty cart
Rules that must always hold
  • Every quantity is greater than zero.
  • One logical entry per product.
  • The total is never negative.
  • An unknown product cannot be added.
  • Quantity cannot exceed available stock — if inventory is enforced here.

How to do it

Most important first.

  • Start from the concept's primitives graph, or draw your own: cart, operations, the pieces from Big Unknown, Smaller Unknown, Known Primitive, the primitives. Draw each primitive once and let several pieces point at it.
  • Mark every node you can already write. The learning order is the unmarked nodes, bottom first — and the number of them is usually smaller than the pile felt.
  • For each unmarked primitive, write the operation that will test it next to it: "Arrays → findItem". That is the reason to learn it and the proof that it was learned (When the Rung Below Is a Foundation).
  • Draw alternatives sideways with a dotted edge and a condition: "Map — if lookup must not scale with the cart" (Why This Data Structure?).
  • List what has no edge into the graph and write "not for this cart" next to it. Keep the list; it is the answer to "shouldn't I learn classes first?"

Worked on a concrete problem

The move has to produce something. This is what it produced.

  • The cart's graph, from its own record. cart → addItem, removeItem, total. addItem → find-existing, append, reject. find-existing → loop, compare-ids, return-early. removeItem → filter → loop, compare-ids, array. total → loop, arithmetic. Primitives: loop (needs array), compare-ids (needs conditional), return-early (needs function), array, conditional, function, arithmetic.
  • A learner marks what they can write: conditionals, functions, arithmetic — yes. Arrays — reading one, yes; looping, unsure. return-early — never done. Unmarked: loop, return-early. Two nodes, both under find-existing, both tested by findItem. The forty-item list has become two.
  • The learning order: loop first (return-early needs somewhere to return from), tested by printing each product id; then return-early, tested by findItem returning the Laptop entry on the first match. Then find-existing is writable, then addItem, then — because filter is the same loop with the comparison flipped — removeItem needs nothing new.
  • Sideways: Map, dotted, "when find must be O(1) average". Not connected: classes (the reference cart is plain functions over a plain object), async (nothing waits), inheritance (nothing is specialised). Written down as "not for V1", so the question does not return every evening.

How you know it worked

What now exists that did not before, and what question you can now ask.

  • The graph fits on one page, and every primitive appears once no matter how many operations need it.
  • Each unmarked node has an operation next to it that will prove it — the learning list is also the test list.
  • The order was read off the graph, bottom up, rather than off a book's table of contents.
  • There is a written "not for this cart" list, and it contains things a generic curriculum would have put first.

The questions you can now ask

The field this whole domain exists for. After this lesson, these are the questions to put to an unfamiliar problem.

Next questions
  • ?What does this operation need, and what does each of those need — drawn once each?
  • ?Which nodes can I already write, and which is the lowest one I cannot?
  • ?Which operation will prove each missing node, and can I write that operation as soon as the node is filled?
  • ?What has no edge into this graph — and am I about to learn it anyway?

What can go wrong

How the move itself fails
  • Drawing the whole language. A graph that includes every construct you have heard of is the forty-item list with arrows; the graph is of this problem's needs, and its top node is the cart.
  • Putting alternatives under the thing they replace. Map under Array makes Map a prerequisite of the cart, which it is not; sideways with a condition keeps it optional.
  • Learning the bottom layer completely before testing anything. Even bottom-up, each node should be proven by the operation above it as soon as that operation is writable — the graph orders the work, it does not batch it.
  • Treating "not for this cart" as "not ever". Classes arrive with the concept that needs identity and behaviour together; the list is scoped to V1 of this problem and should say so.
What the move costs
  • A graph for one concept is narrower than a curriculum; it will not warn you about the construct the next concept needs. It is redrawn per concept, and the overlap is where breadth comes from.
  • Drawing takes time that a learner who already knows the primitives does not need to spend; for them the graph is the concept's record, read once.
  • Leaving classes and async off the list is efficient for the cart and can look, to a colleague with a curriculum in mind, like skipping fundamentals. The written "not for V1" note is the answer.
Misreads
  • "So learn bottom-up." Learn bottom-up *within the graph of this problem*, which is a different thing from studying every foundation before any problem. The top node is what makes the bottom nodes worth learning.
  • "Maps are a prerequisite for the cart." They are an alternative representation. The graph draws them beside the array; the edge only becomes solid when a requirement — large carts, structural uniqueness — makes the map the choice.
  • "The graph is the DSA roadmap." It is the roadmap for one concept and hands off to DSA at the primitives. The DSA domain's own order is for learning structures in general; this graph says which one this problem needs first.

Where this applies

Problem-solving advice is stated as universal far more often than it is. These labels say what each method is specific to — and where CONTESTED appears, the note gives the strongest form of the opposing view.

  • GENERALAny concept has a prerequisite graph with itself at the top, and reading it bottom-up for order and sideways for alternatives works for a rate limiter or a job queue as well as a cart — the nodes change, the reading does not.
  • TEAM-SPECIFICFor a solo learner the unmarked nodes are language primitives; for an engineer new to a domain they are domain operations — "reserve stock" — and the primitives are all marked. Same graph, different frontier.
  • ILLUSTRATIVEThe forty-item list, the two unmarked nodes and the chapter numbers are invented to show the shape; the graph itself is the shopping-cart concept's own primitives record.

Where the depth lives

This domain asks the question and hands the answer off by name.

Software Designsingle-responsibility
Further
  • The manifesto's "What do I need to learn?" map at /manifesto/layers does this at the scale of a whole product; this graph does it for one concept.