In an imperative simulation that assigns each entity a new position every tick, what becomes of the previous position?
answer
- one cell, one current value
- a command, not an equation
- the write lands in place
- nothing retains the previous contents
- save it yourself or lose it
basics
~20 sAssignment in the imperative model is a destructive update: the storage cell that held the old position now holds the new one. The previous value survives only if the program copied it somewhere before the write.
solid answer
~40 sImperative computation advances by destroying state. `entity.position = next` does not produce a second world alongside the first; it writes over the cell that held the old position, and after the write nothing in the program can recover it. That is why a tick loop needing last tick's value — to interpolate a render, to resolve a collision against where the entity used to be, to undo a rejected move — has to keep an explicit copy before it starts writing. It is also why a read has a *time*: the same expression `entity.position` answers differently before and after the assignment. A style built on values rather than cells would instead produce a new world and leave the old one intact; cheap in-place update is exactly what this paradigm buys by giving that up.
code
pseudocode · 10 lines// destructive: the old position is gone after line 2
function advance(entity, delta)
entity.position = entity.position + delta
return entity.position
// keeping it: copy the value out before the write
function advanceKeepingPrevious(entity, delta)
previous = entity.position // a copy of the value
entity.position = previous + delta
return pair(previous, entity.position)go deeper
Recall the two steps: evaluate the right-hand side against the current state, then overwrite the named location. Say plainly that the old value is gone and that a copy has to be taken before the write if you need it.
Explain that a name denotes a location, not a value, so a read is an observation with a time attached. Show why copying a record's reference is not the same as copying the value you wanted to keep.
Show the judgment in a real loop: when to copy one field, when to double-buffer the whole world, when to keep a change log instead. Name what each costs in memory and in the confusion it removes.
Frame it as a house rule. Decide where in a system state may be updated in place and where steps must produce values, and be able to say what that boundary buys in debuggability against what it costs in allocation.
## The store and the command An imperative program is a **store** — a set of named locations, each holding exactly one value — together with a sequence of **commands** that change it. Assignment is the primitive command. It names a location on the left and an expression on the right, and its meaning is two steps in a fixed order: evaluate the expression against the store as it is *now*, then **overwrite** the named location with the result. Nothing else happens. No second location appears, no record of the previous contents is retained, and no other name in the program is consulted. That is why the style is called imperative. `entity.position = next` is not an assertion that the two sides are equal — read as an assertion it is usually false, since the right side was computed from the left. It is an order: *put this there*. **Destructive update** is the standard name, and the word destructive is doing real work. The old value is not moved, archived or versioned. It is gone. ## What the tick loop loses A simulation that advances a grid of entities one tick at a time feels the consequence immediately. The moment the loop writes `entity.position`, the position the entity held at the start of the tick has left the program's state. Anything that needed it must have saved it first: - **interpolation** between the last rendered frame and this one needs both endpoints, not just the newer one; - **swept collision** — "did this entity cross that wall between ticks?" — needs the segment, and a segment is two points; - **rollback** for an undo, a replay or a move the rules rejected needs somewhere to roll back *to*; - **debugging** ("what was it before?") has no answer the running program can produce, only one a tool recorded from outside; - **change detection** ("did anything move this tick?") needs a before-image to compare against. None of these are exotic, which is why real tick loops keep a previous-state buffer, write into a second grid and swap at the end, or maintain a trail of changes. The paradigm does not hand you the old value; you pay for it deliberately, and the copy is a cost you chose, not something assignment does on your behalf. ## Destructive update against producing a value The contrast is sharpest when the same step is written both ways. | | Destructive update | Producing a new value | |---|---|---| | after the step | one grid, now changed | two grids: before and after | | reading "before" | impossible unless copied first | ask the old value; it is still in hand | | what a name means | whatever the cell holds *now* | the value the name was bound to | | reading twice | may give two answers | gives the same answer | | what pins the order | every read and write of a shared cell | only real data dependencies | Neither column is free. In-place update is why a simulation can advance thousands of entities without allocating a new world each tick; producing values is why a step can be re-read, retried and reasoned about without knowing what ran before it. ## Why a read has a time In a value-based style a name denotes a value, and asking for it twice is the same question twice. In an imperative store a name denotes a *location*, and reading is an **observation of current contents**. So "what does `entity.position` equal?" is an incomplete question in imperative code. The honest form is "at which point in the sequence?" This is the root of most first-year confusion about assignment: a beginner reads `count = count + 1` as an equation and objects that nothing equals itself plus one. It is not an equation. It is: take what is in `count`, add one, put the result back in `count`. ## Keeping the old value on purpose Three standard moves, in increasing cost and increasing safety: 1. **Copy the field before the write.** Cheapest, and enough when one value is needed for the rest of the tick. It fails quietly if you copy a reference to a record rather than the value you meant. 2. **Double-buffer the world.** Read from the current grid, write into a second one, swap the two at the end of the tick. Every read during the tick then sees a consistent start-of-tick world, which also removes the question of whether an entity updated earlier in the loop should be visible to one updated later. 3. **Record the change, not the state.** Keep a log of (location, old value, new value). Memory grows with the number of edits rather than the size of the world, and an undo is the log replayed backwards. What an interviewer is listening for here is not the definition. It is whether you know that assignment has a *victim* — that the value you overwrote was state the program used to have, and that the paradigm's convenience and its main hazard are the same mechanism seen from two sides.
- Why does `count = count + 1` confuse readers who expect an equation?Because the symbol is read as a claim of equality, and as a claim it is false. The statement is a command with an order inside it: evaluate `count + 1` against the current store, then replace the contents of `count` with that result. The left side names a location; the right side names a value.
- A loop saves an entity into a second variable and later reads the saved position. Why might it still see the new value?Because saving the *record* saves a reference, not a snapshot. Both names then reach the same cell, so the write through one is visible through the other. Saving the field's value instead — copying the position itself — is what preserves the earlier state.
- How does double-buffering a grid change what a read during a tick means?It fixes the time of every read. All reads come from the frozen start-of-tick grid and all writes go to the other one, so an entity updated late in the loop sees the same world as one updated early. Without it, the answer depends on position in the loop.
A whiteboard cell holds one number: writing the new one wipes the old, and if you wanted it you should have photographed the board first. A notebook, by contrast, gets a new line and keeps every earlier one.
saying these in an interview costs you the question
- Says assignment creates a new value and leaves the old one reachable
- Believes saving the entity record into a variable preserves its earlier position
- Assumes the runtime keeps one prior version of every location
- Reads assignment as asserting the two sides are equal
- Thinks reading a field twice in one tick must give the same answer