3Lesson 3 of 4

Reading code: syntax as communication

When minds collaborate, one writes while another reads and verifies. Reading is the bottleneck.

Programs must be written for people to read, and only incidentally for machines to execute.

Harold Abelson & Gerald Jay Sussman,Structure and Interpretation of Computer Programs (1984)
Conceptualize

In the age of AI collaboration, the bottleneck has shifted. Writing code is increasingly automated or shared. Understanding code is not.

When minds collaborate—human and AI, or any combination—there is always code that one mind wrote and another needs to understand. No mind can verify code without reading it. No mind can spot a subtle bug without tracing the logic. No mind can improve code without first understanding what it does.

The mental model shift

Most beginners think code is instructions for computers. That is technically true but deeply misleading.

Code is a message from one mind to another that happens to be executable by a computer.

Computers do not care if a variable is named x or userEmailAddress. They do not read comments. They just execute. But the next mind reading this code—a collaborator, a reviewer, or a future version of the original author—needs to understand what is being accomplished and why.

Code explains intent. Names document purpose. Structure reveals logic. Learning to read code fluently means learning to extract this meaning.

This applies regardless of who wrote the code. Human-authored, AI-generated, or co-written—the reading process is the same.

Specify

By the end of this lesson, you should be able to answer:

  • 1.How do you read code efficiently (not top-to-bottom like prose)?
  • 2.What are the universal patterns that appear in every language?
  • 3.How do you verify that code does what it claims?
  • 4.How do you know when you do not understand something?

These are precise questions with precise answers. If you can answer them, you can read code from any source.

Generate

Four strategies for reading code

Reading code is different from reading prose. You do not start at the top and read linearly to the bottom. You use different strategies depending on what you need to know:

1. Start with the big picture

Before diving into details, ask: What does this code do? Read function names, comments, and the overall structure. Ignore implementation for now.

2. Identify inputs and outputs

What goes in? What comes out? If it is a function, look at the parameters and the return statement. This tells you the contract of what the code promises to do.

3. Trace the main path, then edge cases

Follow the happy path first—what happens when everything works normally? Then look for conditionals and error handling to understand edge cases.

4. Read the names—they tell you intent

Good code uses meaningful names. A variable called isUserLoggedIn tells you more than flag or x. Names are documentation.

Universal patterns

No matter what language you read, you will encounter these patterns repeatedly. Learn to recognize them and you can read code in any language.

Variable assignment

// Creating labeled boxes to store values
let username = "alice";
const maxAttempts = 3;
let isValid = false;

Read as: “Store this value under this name so I can use it later.”

Function calls

// Using bundled code by calling its name
let result = calculateTotal(items, taxRate);
sendEmail("user@example.com", message);

Read as: “Do this named task with these inputs.” The function might return something (like calculateTotal) or just perform an action (like sendEmail).

Conditionals

// Making decisions based on conditions
if (user.age >= 18) {
allowAccess();
} else {
showAgeWarning();
}

Read as: “If this condition is true, do this. Otherwise, do that.” Only one path executes.

Loops

// Repeating an action for each item
for (let item of shoppingCart) {
total = total + calculatePrice(item);
}

Read as: “For each item in this collection, do this action.”

Data structures: Arrays and Objects

// Arrays: ordered lists of values
let colors = ["red", "blue", "green"];
// Objects: collections of labeled values
let user = {
name: "Alice",
age: 28,
email: "alice@example.com"
}

Arrays hold multiple items in order. Objects group related data under named keys. These are the building blocks for representing real-world data.

Reading like the computer

Here is the key to computational empathy: trace through code as the computer would. Let us apply this to a realistic function.

function validatePassword(password) {
// Check minimum length
if (password.length < 8) {
return {
valid: false,
reason: "Password too short"
}
}
// Check for numbers
if (!containsNumber(password)){
return {
valid: false,
reason: "Must include a number"
}
}
// All checks passed
return { valid: true };
}

Apply the strategies:

  1. Big picture: The function name validatePassword tells us it checks if a password meets certain rules.
  2. Input/Output: Takes a password string, returns an object with valid (boolean) and optionally a reason (string).
  3. Main path: If all checks pass, return { valid: true }. Each check is clearly labeled with a comment.
  4. Edge cases: The conditionals handle failures—too short, missing a number. Each returns immediately with an explanation.

Notice how you understood this without needing to know how containsNumber works. That is the power of good names and clear structure.

*

Key insight

Good code reads like prose: “Validate password. If password length is less than 8, return invalid with reason 'Password too short.'” Bad code reads like a puzzle to decode. When evaluating code, ask: Can a mind understand what this does by reading the names and structure?

Try it yourself

Apply the four strategies to this function. Answer the questions before revealing the answers.

function processOrder(cart, user) {
let subtotal = 0;
for (let item of cart) {
subtotal = subtotal + item.price;
}
let discount = 0;
if (user.isPremium) {
discount = subtotal * 0.1;
}
let total = subtotal - discount;
return {
subtotal: subtotal,
discount: discount,
total: total
}
}

Questions:

  1. What does this function do? (Big picture)
  2. What are the inputs and what does it output?
  3. What is the main path? When does it branch?
  4. If user.isPremium is false, what is discount?
  5. If cart has items priced 10, 20, 30 and the user is premium, what is total?
Show answers

1. Calculates order totals with premium member discounts.

2. Input: cart (array of items with prices) and user (object with isPremium property). Output: object with subtotal, discount, and total.

3. Main path: sum item prices, check premium status, calculate final total. Branches at the premium check.

4. Discount is 0 (the else is implicit—if not premium, discount stays at its initial value of 0).

5. Subtotal = 60, discount = 6 (10% of 60), total = 54.

Critique

Now we stress-test the approach. When does it break down? What should make you pause?

When names lie

The reading strategies depend on names being honest. But sometimes they are not:

// Misleading name
function validateEmail(email) {
return email.includes("@");
}

This function claims to validate an email but only checks for an @ symbol. “a@b” would pass. The name overpromises what the code delivers.

Recognizing when you do not understand

This is epistemic humility applied to code. Here are signals that you should pause:

  • *
    You cannot explain what a line does in plain language. If you cannot say it simply, you do not understand it yet.
  • *
    You are not sure what a function returns. Trace it through or test it. Guessing leads to bugs.
  • *
    You are copying code you cannot modify. If you could not change it to do something slightly different, you do not understand it.
  • *
    The code uses syntax you have never seen. Stop and look it up. Do not assume.

When you notice these signals, you have two options: dig deeper (trace the code more carefully, read documentation) or ask another mind for help (collaborator, AI assistant, or online resources).

Common issues in code from any source

Whether code comes from a human collaborator, an AI, or an open source project, watch for these:

  • *
    Generic names: result, temp, data when something specific would be clearer.
  • *
    Over-engineering: 20 lines when 5 would do. Check if there is a simpler approach.
  • *
    Off-by-one errors: Using > when it should be >=, or looping one too many/few times.
  • *
    Missing edge cases: What if the input is empty? Null? What if the user is already logged in?
  • *
    Intent mismatch: The code may solve a slightly different problem than what was requested. Verify it matches the actual requirement.

What this approach does not cover

We are assuming you can read the code in front of you. Real codebases add complexity: code spread across many files, dependencies on external libraries, framework conventions you need to learn. These require broader context that comes with experience. The core reading skills still apply—you just need to gather more information first.

Refine

You have built a mental model for reading code. Specified what it should answer. Practiced with examples. Critiqued its limits.

What we learned

  • Code is communication between minds that happens to be executable
  • Four strategies: big picture, inputs/outputs, trace paths, read names
  • Universal patterns appear in every language: variables, functions, conditionals, loops, data structures
  • Computational empathy: trace code as the computer would execute it
  • Epistemic humility: recognize when you do not understand and either dig deeper or ask for help
  • Code from any source needs critical reading—names can lie, edge cases can be missing

What is next

You can now read code from any source—human or AI. But reading is only half of collaboration. The next lesson covers the full picture: how minds work together to write and verify code.

The loop continues.

Why this matters for mind + mind collaboration

In collaboration, there is often a division of labor: one mind writes, another reads and verifies. Reading is the bottleneck. The writing mind can generate code quickly, but verification requires understanding—and understanding cannot be rushed or automated.

The mind that reads well can catch bugs, suggest improvements, and confidently modify code from any source. This is the skill that makes collaboration work.

The best programs are written so that computing machines can perform them quickly and so that human beings can understand them clearly. A programmer is ideally an essayist who works with traditional aesthetic and literary forms as well as mathematical concepts, to communicate the way that an algorithm works and to convince a reader that the results will be correct.

Donald Knuth,Selected Papers on Computer Science (1996)

Now practice what you've learned

The reading gives you the mental model. The exercises make it stick. Week 3 exercises focus on code explanation: explaining unfamiliar programs in plain language.

Start Week 3 Exercises

15 exercises · 5-6 hours

Or continue to Lesson 4: Mind + Mind Collaboration to complete the readings first