Variables and Assignment

Every program you will ever read, protect, or reverse engineer is built out of one primitive move: give a value a name, then use the name. This lesson pins down exactly what that move means, because half of what obfuscation does later in this course is attack the name side of it while leaving the value side untouched.

Picture a wall of small labelled boxes. Writing level = 7 puts the number 7 into a box and sticks the label level on the front. From then on, whenever the program mentions level, the machine walks to that box and reads whatever is inside right now. The label never changes what is in the box. It only helps you find it.

More precisely, a variable is a binding: an entry in the program's state that associates a name with a current value. Reading the variable looks the value up. Assigning to it replaces the value. The state table you watched in the Level 0 execution visualizer is literally this: names on the left, current values on the right.

Assignment is an action, not an equation

The = symbol trips up almost everyone at first, because in mathematics x = x + 1 is nonsense. In a program it is an instruction with a strict order of operations: first the right-hand side is fully evaluated using the current values, then the result is stored into the name on the left. So x = x + 1 means take whatever x holds now, add one, and store the answer back under the same name.

That right-side-first rule is worth burning in, because it explains behaviour that otherwise looks mysterious. It is also why swapping two variables needs a third one: the moment you assign over a name, its old value is gone.

See it in eight languages

The switcher below shows the same variable declarations in all seven course languages. Notice what changes: the keyword (local, let, nothing at all, a declared type in Java and Go, a $ sigil in PHP) and the spelling of the empty value. Notice what never changes: a name is bound to a value, and the name is arbitrary.

Try it yourself

The playground below runs a tiny teaching language inside a sealed interpreter. Nothing you type can touch this page or your machine. Run the program, then break it on purpose: reorder the lines, reuse a name, assign a variable to itself plus one.

Try deleting the temp line in the swap and writing a = b directly. Step through it in your head first: the moment a is overwritten, the old value of a no longer exists anywhere, so there is nothing left to put into b. Assignment destroys. That is not a flaw, it is the whole design.

The name is for you, not the machine

Here is the observation that matters for the rest of this course. The machine never uses the name playerHealth to do anything. By the time code runs, names have been reduced to storage locations. Which means a program where every name is replaced by meaningless noise behaves identically to the original.

Readable names are a gift the author gives to future readers. Identifier renaming, the first real obfuscation technique in Level 6, is simply the decision to take that gift back before shipping. Nothing breaks, because nothing ever depended on the names.

One expert-level caveat: the claim "names never matter at runtime" holds for locals, but some languages let code look names up dynamically, through reflection, string-keyed globals, or environment tables. Any name that can be reached that way is no longer free to rename, and every serious obfuscator has to detect those cases and leave them alone or fix up the lookups. Scope-aware renaming is harder than it looks, and Level 4 covers why.

A variable binds a name to a current value. Assignment evaluates the right side first, then stores. The value is for the machine; the name is documentation for humans, which is why it can be destroyed without changing behaviour.

Frequently asked questions

Is a variable the same thing as memory?

A variable is a name for a location that holds a value. The Level 0 lesson on the stack and the heap covers where those locations physically live; this lesson is about the naming layer on top, which is the part obfuscation attacks.

Why do some languages need let or local and others need nothing?

It is a design choice about explicitness. Declaring a variable tells the language exactly where the name is born, which helps catch typos and controls scope. Languages without declarations infer it from the first assignment. The underlying binding of name to value is identical.

Keep learning

  • Programming Fundamentals, One Idea in Seven Languages
  • Strings, Numbers, and Booleans
  • Identifier Renaming: The First Layer, Never the Last
  • Where Values Live: Memory, Stack, and Heap
  • Lua Obfuscator
  • JavaScript Obfuscator
  • Python Obfuscator

All lessons