Students reading and discussing English work together in a small-group lesson at Singapore English Tuition Centre.

How to Read | Class No.0036 | The Computational Read — Read Algorithms, Code, Data, State, Branches and Complexity Without Losing What the Machine Is Actually Doing

Class No.0027: The Technical Read · Class No.0020: The Systems Read · Class No.0023: The Mathematical Read

SETC-HOWREAD-0036 · How to Read

Code is text, but reading code is not the same as reading prose.

A program can look simple line by line and behave unexpectedly because state changed three functions earlier. A loop can be correct for nine inputs and fail on the tenth. A variable name can suggest one meaning while runtime data carries another. A branch can hide a path the reader never mentally executed. A fast solution can become unusable when input size grows.

The Computational Read teaches readers to follow what the machine actually does: inputs, state, control flow, data, dependencies, tests and complexity.

Computer science now explicitly values reading code

The 2026 CSTA PK–12 Computer Science Standards retain algorithms, programming, data and systems as core concepts and explicitly expand programming beyond writing code to include reading, evaluating, modifying and debugging programs.

That shift matters. Programming competence includes comprehension.

Start with the program’s contract

Before line one, ask:

  • What input arrives?
  • What output is expected?
  • What assumptions hold?
  • What side effects occur?
  • What errors are possible?

A function is easier to read when its job is known.

Read examples before internals

If documentation provides input-output examples, use them to form an initial behavioural model.

Then read implementation to see how behaviour is produced.

Source code is not runtime behaviour

Code describes instructions. Runtime behaviour depends on:

  • input;
  • state;
  • environment;
  • dependencies;
  • timing;
  • errors.

Reading must simulate execution.

Trace one concrete case

Choose a small input and follow it.

Write changing values beside the code.

Concrete tracing turns abstract control flow into observable state transitions.

Variables have values and roles

A variable can represent:

  • counter;
  • accumulator;
  • flag;
  • index;
  • configuration;
  • object reference;
  • current state.

Role often matters more than name.

Name can mislead

A variable called total may actually contain a subtotal, stale value or count.

Trust assignments and invariants, not labels alone.

State is memory of the computation

State answers:

What does the program know right now that will change what happens next?

State can live in variables, objects, files, databases, caches or external services.

Local code can depend on distant state

A function may read global configuration or mutate shared data.

That makes local reasoning harder.

Ask what dependencies enter invisibly.

Control flow decides which code runs

Read:

  • sequence;
  • condition;
  • loop;
  • function call;
  • exception;
  • early return.

Indentation or braces are structural syntax.

Branches create alternate worlds

For each if, ask:

  • What makes condition true?
  • What happens if false?
  • Can both branches reach the same later state?
  • Is one branch impossible under prior assumptions?

Boolean conditions need literal reading

Translate compound conditions into words.

A and B differs from A or B.

Negation can reverse the intuitive reading.

Guard clauses narrow state

An early return such as “if input is invalid, stop” tells the reader that code below can assume validity.

Use guards as proof steps.

Loops require an invariant

Ask:

  • What changes each iteration?
  • What remains true?
  • What causes termination?
  • Can termination fail?

A loop is a repeated state transition.

Off-by-one errors are reading errors

Inclusive and exclusive boundaries matter.

Read whether a loop handles indices 0 through n−1, 1 through n, or some other range.

Empty input is a real path

Ask what happens with:

  • zero items;
  • one item;
  • maximum size;
  • missing data;
  • duplicate data.

Boundary cases reveal assumptions.

Functions compress reasoning

A call such as sort(items) hides implementation behind a contract.

Ask:

  • what function promises;
  • whether it mutates input;
  • what it returns;
  • what errors it can raise;
  • its cost.

Abstraction reduces reading load

You do not need to understand every implementation detail at once.

Read at the level needed for the current task, then descend when behaviour depends on internals.

Call stack is reading context

When a function runs, ask who called it and what parameters were passed.

A line can behave correctly in one call context and incorrectly in another.

Recursion needs a base case

Read:

  • base case;
  • recursive step;
  • progress toward base;
  • returned value.

If progress is absent, recursion may not terminate.

Data structures shape algorithms

Array, list, set, map, stack, queue, tree and graph support different operations efficiently.

Read why a structure was chosen.

Order can be meaningful or accidental

A set may not preserve the same ordering assumptions as a list.

Do not rely on order unless the data structure or language contract guarantees it.

Identity and equality differ

Two objects can contain equal values while being distinct objects.

Some languages distinguish reference identity from value equality.

Read semantics, not appearance.

Mutation changes future meaning

If an object is modified in one place, another reference to the same object may observe the change.

Aliasing can make code surprising.

Immutability simplifies reasoning

Values that cannot change reduce the number of possible state histories.

This is one reason immutable designs can be easier to reason about.

Input validation defines trustworthy state

Before computation, code may check type, range, presence or format.

Read what assumptions become valid after validation.

Parsing is translation

A text input can become tokens, numbers, syntax trees or structured objects.

Errors can arise before the main algorithm begins.

Data cleaning changes evidence

For data programs, inspect:

  • missing-value handling;
  • duplicate removal;
  • filtering;
  • type conversion;
  • outlier rules.

Analysis output depends on preprocessing.

One line of data transformation can change population

A filter can silently exclude cases.

Read inclusion logic like a research-methods decision.

Algorithms are procedures with guarantees

Ask:

  • What problem does the algorithm solve?
  • Under what assumptions?
  • Is it exact or approximate?
  • Does it always terminate?
  • What resources does it require?

Correctness and efficiency are different

An algorithm can return correct results and still be too slow or memory-intensive at scale.

Complexity describes growth

Big-O notation describes how resource use grows as input size grows, abstracting away machine-specific constant factors.

Do not read O(n²) as “takes n² seconds.”

Small input can hide bad scaling

An algorithm may feel fast on 100 items and fail badly on 10 million.

Always ask how work grows.

Worst case, average case and amortised analysis differ

Know which performance claim is being made.

Optimisation can harm readability

Faster code is not always better if complexity increases without meaningful performance benefit.

Read trade-offs.

Tests are executable claims

A test states that under a particular input or state, the program should produce a specified behaviour.

Read tests to discover intended contract.

Passing tests do not prove absence of bugs

Tests cover selected cases.

Ask what is not tested.

Property-based thinking broadens testing

Instead of only examples, ask what property should always hold.

Example:

Sorting should preserve item count and produce nondecreasing order.

Error messages are evidence

Read:

  • error type;
  • message;
  • stack trace;
  • location;
  • state that triggered it.

The visible line may be where failure surfaced, not where the faulty assumption began.

Debugging is causal reading

Trace:

symptom → state → branch → prior mutation → root cause

Do not patch the first visible symptom without understanding propagation.

Logs are runtime narratives

Timestamps and events reveal sequence.

But noisy logs can overwhelm. Search for state changes around failure.

Concurrency changes the reading model

When multiple tasks run concurrently, execution order may vary.

Shared state can produce race conditions.

A line-by-line single-thread mental model may be insufficient.

Asynchronous code separates call from completion

A function can start work now and finish later.

Read promises, futures, callbacks or async/await according to language semantics.

External systems are part of behaviour

Network, database, file system and API failures must be included in the program model.

Code that works offline may fail under latency, timeout or partial response.

Interfaces are contracts between components

Read:

  • accepted inputs;
  • returned outputs;
  • error behaviour;
  • version;
  • side effects.

Integration bugs often begin at contract mismatch.

Version changes can break assumptions

Libraries and APIs evolve.

Read documentation for the actual version in use.

Security reading asks what an attacker controls

For defensive comprehension, identify untrusted inputs, permissions, secrets and trust boundaries.

Do not assume external input is benign.

Least privilege narrows consequences

A component should not need more permission than its job requires.

Reading access scope helps reveal risk.

Data privacy is part of computation

Ask:

  • what personal data is collected;
  • where stored;
  • who can access;
  • how long retained;
  • what is logged.

AI code still has inputs, outputs and failure modes

Machine-learning systems add data, training, model behaviour and probabilistic outputs.

Do not treat AI as magic outside computational reading.

Model output is not source-of-truth by default

Read evaluation, confidence, provenance and downstream verification requirements.

The 2026 CSTA standards treat AI as integrated with core computer science

Current CSTA standards preserve algorithms, programming, data and systems while adding AI and emerging technologies, model interpretation and reasoning, and computing impacts.

That supports a broad Computational Read rather than a code-only one.

Kindergarten: algorithms as ordered steps

Give instructions for a familiar task.

Change one step and observe what happens.

Primary 1: sequence

Use arrows and simple commands.

Primary 2: condition

Introduce:

If it is raining, take an umbrella; otherwise continue.

Primary 3: loops

Repeat a step a fixed number of times and identify what changes.

Primary 4: variables

Use a score or counter whose value changes.

Primary 5: debugging

Find which instruction caused a wrong outcome.

Primary 6: data

Sort, filter and represent a small dataset.

Secondary 1: trace code

Build a variable table across each line.

Secondary 2: functions and abstraction

Read contract before implementation.

Secondary 3: data structures and complexity

Compare two solutions for growing input.

Secondary 4: testing and edge cases

Design tests that target assumptions, boundaries and failure paths.

JC: full program architecture

Map:

input → validation → state → algorithm → dependency → side effect → output → test → failure path

Then identify complexity, security and data assumptions.

The Computational Read protocol

  1. State the program contract.
  2. Identify inputs, outputs and side effects.
  3. Trace one concrete execution.
  4. Track variables and state.
  5. Follow branches, loops and calls.
  6. Inspect data structures and mutations.
  7. Read tests and failure paths.
  8. Check external dependencies and versions.
  9. Evaluate scaling and complexity.
  10. Return to whole-system behaviour.

The Code Reading Card

Contract: ______
Input: ______
Output: ______
State: ______
Main branches: ______
Loop invariant: ______
Dependencies: ______
Complexity: ______
Failure path: ______

Common failure: line-by-line without state

Repair: variable trace.

Common failure: function name becomes behaviour

Repair: inspect contract and implementation where needed.

Common failure: happy path only

Repair: branch and error-path reading.

Common failure: tests equal proof

Repair: untested-case analysis.

Common failure: small-input speed becomes scalability

Repair: complexity reading.

Three learners, three computational-reading failures

Maren can explain each line but loses program state. Her repair is execution tracing.

Iona understands functions but ignores mutation through shared objects. Her repair is identity and alias tracking.

Leonie debugs the visible error line without tracing the earlier state change. Her repair is causal debugging.

A 60-minute Computational Read tutorial

  1. 10 minutes: contract and example.
  2. 10 minutes: variable/state trace.
  3. 10 minutes: branches and loops.
  4. 10 minutes: functions and data structures.
  5. 10 minutes: tests and debugging.
  6. 10 minutes: complexity and whole-system behaviour.

The Computational Read audit

Ask:

  • What is the program supposed to do?
  • What inputs and assumptions exist?
  • What state changes?
  • Which paths can execute?
  • What terminates each loop?
  • What functions mutate data?
  • What external dependencies exist?
  • What tests define intended behaviour?
  • What failure paths are untested?
  • How does resource use grow?
  • Does my mental execution match runtime behaviour?

Reference anchors

Continue through SETC

Final lesson

Computational reading is execution-aware reading.

Do not merely see the code. Run it mentally. Track state. Follow branches. Respect data structure semantics. Read the tests. Search the failure paths. Ask how the work grows when the input grows.

The machine does not execute what the programmer meant.

It executes what the program actually says.

Return to the English Learning Library · Advanced English / General Paper

Continue with the How to Read collection.