Base CS from zero
A variable is a named cell
You already know that memory is a long row of numbered cells, each holding a value at a fixed address. The CPU reads and writes those cells by number: “give me cell 1042”, “write 255 to cell 1042”. That works perfectly for the machine — but it is exhausting for a human programmer.
Imagine writing a program that tracks a user’s score. You would have to remember that “the score lives at address 1042” and never mix it up with “the player count at address 1080”. One slip — one wrong address — and you read the wrong cell. Software written this way is brittle and nearly impossible to reason about.
Every programming language solves this problem the same way: it lets you attach a
name to a memory cell. Instead of “address 1042”, you write score. The name is
stable and readable; the address is managed for you. That named cell is a variable.
This one idea — a human-readable name bound to a cell — underlies everything about how programs store and manipulate data.
After this lesson you can explain what a variable is in terms of a memory cell and a name, distinguish the name from the value it holds, and describe what happens when you declare a variable.
The problem: raw addresses are unmanageable. In the machine’s language, every read and write uses a numeric address. Address 1042 means nothing to a human without a separate note saying “that is where the score is.” As a program grows to dozens of values, keeping those notes consistent becomes the programmer’s entire job — and errors are inevitable.
High-level programming languages were invented, in part, specifically to free programmers from tracking numeric addresses by hand. They introduce the concept of a variable: a named location in memory.
What a variable is: a name bound to a cell. A variable is a pairing of two distinct things:
- A name — a human-readable label like
score,playerCount, ortemperature. The name exists only in the source code. It has no meaning to the CPU. - A memory cell (or contiguous group of cells) — the actual physical location in RAM that holds the value. The CPU works with this cell’s address.
The word binding describes the link between the name and the cell. When a variable
score is bound to cell address 1042, writing score in code means “the cell at
address 1042.” The binding is maintained by the runtime (the program that runs your
code): when it sees the name score, it looks up the address and uses it.
Think of a binding like a sticky label on a physical box. The label (“score”) is what you read; the box is where the value actually lives. You can change what is in the box, but the label stays on the same box.
Declaring a variable: reserving a cell and naming it. Before you can use a
variable, you must declare it. A declaration is the instruction that tells the
runtime: “reserve a memory cell, and let the name score refer to it from this point
forward.”
In TypeScript (and JavaScript), you declare a variable with let or const:
let score = 0;What happens at the machine level:
- The runtime finds a free memory cell (for example, at address 1042).
- It records the binding: name
score→ address 1042. - It writes the initial value
0into that cell.
After the declaration, every use of the name score in the code is translated by the
runtime into a read or write at address 1042. You never see the address; you only see
the name.
Why this works
Why are these called “variables”? The word comes from mathematics, where a variable is
a symbol that can take different values (like x in an equation). In programming the
idea is the same: the name score can “vary” — you can change what value the cell
holds over time. The mathematical term was borrowed when early programming languages
were designed, and it stuck.
The name and the value are different things. This is the most important distinction in this lesson:
- The name (
score) is the label. It is fixed once declared. You cannot change the name partway through the program. - The value (currently
0) is the content of the cell. It can change many times.
These two things are genuinely separate. score and 0 are not the same kind of
thing. score is an identifier — a word in source code. 0 is a value — a bit pattern
stored in a cell. When you write score, the runtime replaces it with the value
currently in the cell; but the name itself is never stored in that cell.
Consider: after the declaration let score = 0, if the program later computes a new
score, the name score still refers to the same cell at address 1042, but the content
of that cell might now be 42. The name did not change; the value in the cell did.
Common mistake
A common confusion: thinking the variable is the value. It is not. The variable is the named cell. The value is what the cell currently contains. You can think of the variable as a container and the value as its current contents. The container persists even when the contents change. This distinction becomes critical when you learn about assignment (the next lesson) and mutation.
The runtime’s job: keeping the name→address table. When the runtime executes your program, it maintains an internal table mapping every live variable name to its memory address. This table is sometimes called a symbol table or an environment in language theory.
Every time the program refers to score, the runtime consults this table:
- “score” → address 1042 → read cell 1042 → return the value there.
When the program writes score = 42, the runtime does:
- “score” → address 1042 → write 42 to cell 1042.
From your perspective as a programmer, names are first-class. From the CPU’s perspective, only addresses exist. The runtime translates between the two worlds.
Tracing a declaration step by step.
let score = 0;
let lives = 3;Declaration of score:
- Runtime finds a free cell. Say it picks address 1042.
- Binding recorded:
score→ 1042. - Initial value
0written to address 1042.
State: address 1042 holds 0, name score refers to it.
Declaration of lives:
- Runtime finds another free cell. Say address 1045.
- Binding recorded:
lives→ 1045. - Initial value
3written to address 1045.
State: address 1045 holds 3, name lives refers to it.
Reading score later in the program:
- The runtime looks up
score→ address 1042. - It reads address 1042 and returns
0.
The programmer writes score and thinks “the current score”. The CPU reads address
1042 and thinks nothing — it just returns bits. The runtime translates one world into
the other.
A variable named 'count' is bound to memory address 200. The cell at address 200 holds value 7. How many memory cells does the variable 'count' directly occupy? Type the number.
After 'let x = 5' the variable x is bound to address 300. Later the program writes a new value 9 to that cell. What address is x now bound to?
A program declares 'let a = 10' and 'let b = 20'. It reads a. What value does it get?
Memory has cells at addresses 0 to 999. A program declares 3 variables. How many distinct named bindings exist after the declarations?
True or false (1=true, 0=false): the name of a variable is stored inside the memory cell that holds the variable's value.
What is the difference between a variable's name and its value?
A variable is a human-readable name permanently bound to a memory cell (or group of cells). The name is a source-code label — it never changes and is not stored in the cell itself. The value is the bit pattern currently held in the cell — it can change at any time. Declaring a variable reserves a cell and records the name→address binding in the runtime’s internal table. Every use of the name in code is translated by the runtime into a read or write at the cell’s address. The CPU only ever sees addresses; the name exists for the programmer’s benefit and is managed by the runtime.