Module 3: State Management

Aspect Particles — Tracking the State of Actions

Here's something that breaks most English speakers' brains: Chinese has no tenses. None. Zero. The verb means "go." It also means "went." And "will go." The verb never changes form.

So how does Chinese track whether something happened, is happening, or has ever happened? Not with tenses. With aspect particles — tiny state flags you attach to verbs to describe the state of an action, not when it occurred.

// English: mutates the verb to encode time
go → went → will go → have gone → am going

// Chinese: verb is immutable. State is tracked separately.
const verb = "去";  // always 去. Forever 去.

verb.completed()    // 去了   — the action completed
verb.experienced()  // 去过   — have gone (at some point in life)
verb.inProgress()   // 在去   — currently going
verb.ongoing()      // 去着   — in a continuing state of going
The mental model: English uses a timeline — it mutates verbs based on where an action sits on a past/present/future axis. Chinese uses a state machine — the verb is immutable, and particles describe the action's current state. Time itself is just a separate data field: 昨天 (yesterday), 明天 (tomorrow). The verb doesn't care about time. The particles care about state.

1. — The .completed() Flag

is the most common aspect particle, and the most misunderstood. It has two distinct uses depending on where it appears. Think of it as an overloaded function.

Use 1: After the verb — action completed

When appears directly after a verb, it marks that the action has been completed. Not "past tense" — completed. The distinction matters.

Chinese Pinyin Code Analogy English
饭。 Wǒ chī le fàn. I.eat.completed(food) I ate. / I've eaten.
一本书。 Tā mǎi le yì běn shū. she.buy.completed(book) She bought a book.
三杯咖啡。 Tā hē le sān bēi kāfēi. he.drink.completed(coffee, 3) He drank three cups of coffee.
// Verb + 了 = action.completed()
// Structure: S + V + 了 + O

我吃了饭。     // I eat.completed() food — I ate
我吃饭。       // I eat food — I eat (general/habitual, no state flag)

// 了 doesn't mean "past tense." It means the action reached completion.
// You can even use it for FUTURE completed actions:
// 你吃了饭再走。 = After you eat (complete eating), then leave.
// The eating hasn't happened yet, but 了 marks its expected completion.

Use 2: End of sentence — state change

When appears at the end of a sentence, it signals a change of state. Something is now different from before. Think: state.changed().

Chinese Pinyin Code Analogy English
下雨 Xià yǔ le. weather.changed("raining") It's raining (now). [Wasn't before.]
Wǒ dǒng le. I.understanding.changed(true) I understand (now). [Didn't before.]
是爸爸 Tā shì bàba le. he.role.changed("father") He's a father (now). [Wasn't before.]
春天 Chūntiān dào le. season.changed("spring") Spring is here (now).
// The overloaded 了:
//
// Position 1: AFTER VERB    → action.completed()
//   我吃了饭 = I ate (action of eating completed)
//
// Position 2: END OF SENTENCE → state.changed()
//   下雨了 = It's raining now (weather state changed)
//
// Sometimes BOTH at once:
//   我吃了饭了 = I've eaten now (action completed AND that's a state change)
//   Translation: "I've eaten" (implying: so I'm no longer hungry / ready to go)

function le(position) {
    if (position === "after_verb")      return "action.completed()";
    if (position === "end_of_sentence") return "state.changed()";
    if (position === "both")            return "action.completed() + state.changed()";
}
The key intuition for 了: It always signals that something is different from what it was. After a verb: the action went from not-done to done. At end of sentence: the situation went from one state to another. If nothing changed, you probably don't need 了. Saying 我是学生 (I am a student) doesn't need 了 — it's a stable fact, not a state change.

2. — The .experienced() Flag

marks that something has been experienced at least once at some point in the past. It doesn't matter when. It doesn't matter how many times. Just: has this ever happened? It's a boolean check.

// 过 = hasExperienced() — returns boolean
user.hasExperienced("China")      // 去过中国 — have been to China ✓
user.hasExperienced("sushi")      // 吃过寿司 — have eaten sushi ✓
user.hasExperienced("skydiving")  // 跳过伞   — have gone skydiving ✓

// It's a lifetime flag. Not about a specific event.
// Not WHEN. Not WHERE. Just: has it ever happened? true/false.
Chinese Pinyin Code Analogy English
中国。 Wǒ qù guo zhōngguó. I.go.experienced("China") I've been to China (at some point).
日语。 Tā xué guo rìyǔ. she.study.experienced("Japanese") She has studied Japanese (before).
这个电影。 Wǒ kàn guo zhège diànyǐng. I.watch.experienced(thisMovie) I've seen this movie (before).
北京烤鸭 Nǐ chī guo Běijīng kǎoyā ma? you.eat.experienced("PekingDuck")? Have you (ever) eaten Peking duck?

了 vs 过 — The Critical Difference

This is where beginners get confused. Both seem to be about "the past." But they're tracking completely different things.

Particle Chinese Pinyin What It Means Analogy
我去中国。 Wǒ qù le zhōngguó. I went to China. (specific completed trip) trip.completed()
我去中国。 Wǒ qù guo zhōngguó. I've been to China. (life experience) user.hasExperienced("China")
// 了 = event log entry — a specific action completed
// 过 = achievement badge — have you ever done this?

// 了 answers: "Did this specific action finish?"
git log --oneline | head -1   // 去了中国 = latest commit: "went to China"

// 过 answers: "Does this appear anywhere in the full history?"
git log --all --grep="China"  // 去过中国 = China appears in commit history

// A developer who has "deployed to production" (过) is different from
// a developer who "deployed to production just now" (了).
// 过 = "I've done this before, I know what it's like"
// 了 = "I just did this specific thing"
Negation difference: To negate 了, use : 我没去中国。 (I didn't go.) To negate 过, use + verb + : 我没去过中国。 (I've never been to China.) Note: when you negate with , the 了 drops off, but the 过 stays. The experience flag persists — you're saying the flag was never set.

3. — The .ongoing() Flag

marks a continuing state. Not an action in progress — a state that persists. The door is open. The light is on. He's wearing a hat. These describe how things currently are, not what someone is actively doing.

// 着 describes persistent state, not active action
// Think: property values, not method calls

door.state = "open";       // 门开着     — the door is (standing) open
light.state = "on";        // 灯亮着     — the light is on
he.wearing = "red_shirt";  // 他穿着红衣服 — he's wearing red clothes

// These are all DESCRIPTIONS of current state.
// Nobody is actively "opening" the door right now — it's just open.
// Nobody is actively "turning on" the light — it's just on.
Chinese Pinyin Code Analogy English
Mén kāi zhe. door.state = "open" The door is open.
帽子。 Tā dài zhe màozi. he.head = "hat" He's wearing a hat.
墙上一幅画。 Qiáng shàng guà zhe yì fú huà. wall.display = painting A painting hangs on the wall.
一杯咖啡。 Tā ná zhe yì bēi kāfēi. she.holding = coffee She's holding a cup of coffee.
窗户 Chuānghu kāi zhe. window.state = "open" The window is open.
着 is about STATE, not ACTION. 门开着 doesn't mean someone is currently performing the action of opening the door. It means the door exists in an open state. It's the difference between door.open() (calling the method) and door.isOpen === true (reading the property). 着 is the property read.

4. — The Event Loop

If 着 describes a persistent state, (before a verb) describes an action that's currently executing. Right now. At this moment. It's the closest Chinese gets to English's "-ing" form.

// 在 + verb = currently executing
// Think: the action is on the call stack RIGHT NOW

while (true) {  // the event loop
    if (action.isRunning()) {
        // 在 marks this
        // 我在吃饭 = I am eating (right now, on the stack)
    }
}

// Often paired with 呢 (ne) at end of sentence for emphasis:
// 我在吃饭呢。 = I'm eating! (can't you see I'm busy?)
Chinese Pinyin Code Analogy English
吃饭 Wǒ zài chīfàn. I.eating.isRunning() // true I'm eating (right now).
睡觉 Tā zài shuìjiào. she.sleeping.isRunning() // true She's sleeping (right now).
他们开会 Tāmen zài kāihuì ne. they.meeting.isRunning() // true! They're in a meeting!
什么 Nǐ zài zuò shénme ne? you.currentTask.getName()? What are you doing?
中文。 Wǒ zài xué zhōngwén. I.studying("Chinese").isRunning() I'm studying Chinese (right now).

在...呢 vs 着 — What's the Difference?

Both relate to "something happening now." But they're different:

// 在 = process is ACTIVELY EXECUTING on the call stack
我在写代码。     // I am writing code (right now, actively doing it)
// Like: top of `ps aux` — it's the running process

// 着 = state is PERSISTING in memory
门开着。         // The door is open (just sitting there, being open)
// Like: a value stored in a variable — it persists

// Test: Can you catch someone "in the act"?
// Yes → 在    (他在跑 = he's running — you see him running right now)
// No  → 着    (门开着 = door is open — nobody is actively opening it)
The particle: Adding at the end of a sentence is like adding an exclamation point to your status update. 我在忙呢 = I'm busy! (It emphasizes the ongoing nature — "I'm in the middle of something here!") You can even drop 在 and just use 呢 alone: 他睡觉呢 = He's sleeping (softened, casual tone).

5. The Decision Flowchart

When you want to describe the state of an action, run this decision tree:

function chooseAspectParticle(situation) {
    // Is the action happening RIGHT NOW, actively?
    if (situation.isActivelyExecuting)
        return "在...呢";   // 我在吃饭呢 — I'm eating right now

    // Did a specific action reach completion?
    if (situation.actionCompleted)
        return "了";        // 我吃了饭 — I ate (completed)

    // Has this been experienced at least once (ever)?
    if (situation.hasBeenExperienced)
        return "过";        // 我吃过寿司 — I've eaten sushi (at some point)

    // Is something in a continuing/persistent state?
    if (situation.stateIsPersisting)
        return "着";        // 门开着 — the door is open (ongoing state)

    // Did a situation change from what it was before?
    if (situation.stateJustChanged)
        return "sentence-final 了";  // 下雨了 — it's raining now

    // Just stating a fact, habit, or general truth?
    return null;            // 我喝咖啡 — I drink coffee (no particle needed)
}
Question to Ask Particle Example English
Is it happening right now? ... 他在做饭呢。 He's cooking (right now).
Did the action complete? V + 他做了饭。 He cooked. (action done)
Has this ever happened? V + 他做过饭。 He's cooked before. (has the experience)
Is there an ongoing state? V + 电饭锅开着。 The rice cooker is on. (persisting state)
Did the situation change? Sentence + 饭好了。 The food's ready! (state changed)
Just a general fact? (none) 他做饭。 He cooks. (habitual, no aspect)

6. Common Mistakes — Bug Report

Here are the bugs most beginners ship. Let's patch them.

Bug #1: Using 了 for everything past

// BUG: Treating 了 like English past tense
// "Last year I lived in Beijing" — tempting to slap 了 on it

// WRONG thinking: past = 了
去年我住了在北京。  // ✗ Garbled

// CORRECT: 了 is for specific completion, not general past situations
去年我住在北京。    // ✓ Last year I lived in Beijing.
// No 了 needed — you're describing a past situation, not a completed action.
// The time word 去年 already tells us it's past.

// Use 了 when there's a SPECIFIC completed event:
去年我去了北京。    // ✓ Last year I went to Beijing. (specific trip, completed)

Bug #2: Confusing 了 with 过

// BUG: Using 了 when you mean 过, or vice versa

// Scenario: Someone asks "Have you ever been to Japan?"
// They're asking about your LIFE EXPERIENCE → use 过

我去过日本。  // ✓ I've been to Japan. (experience exists in my history)
我去了日本。  // ✗ This answers "Did you go to Japan?" about a specific trip.

// Scenario: Your friend asks "Where did you go last week?"
// They're asking about a SPECIFIC COMPLETED action → use 了

我去了日本。  // ✓ I went to Japan. (specific trip, completed)
我去过日本。  // ✗ This answers "Have you ever been?" — wrong question.

// Rule of thumb:
// "Have you ever..." → 过
// "Did you (specifically)..." → 了

Bug #3: Forgetting that 着 is about state, not action

// BUG: Using 着 to mean "is doing"

// WRONG: Trying to say "He is opening the door"
他开着门。  // This means "The door is open" (state), not "He is opening it" (action)

// RIGHT: To say "He is opening the door" (active action):
他在开门。  // ✓ He's opening the door (在 = actively doing it right now)

// 着 = the door's property `.isOpen` reads `true`
// 在 = the `openDoor()` function is currently on the call stack

Bug #4: Double-negating with 没 and 了

// BUG: Using 没 and 了 together

// WRONG:
我没吃了饭。  // ✗ 没 and verb+了 conflict

// CORRECT:
我没吃饭。    // ✓ I didn't eat. (没 already implies the action didn't complete)

// When you negate with 没, drop the 了.
// 没 already cancels the completion — keeping 了 is a contradiction.
// It's like writing: !action.completed().completed()  // makes no sense

7. The Full State Machine

Let's see all four markers side by side using the same verb: (to eat).

Aspect Chinese Pinyin English State
None (bare verb) 我吃饭。 Wǒ chīfàn. I eat. (general fact) IDLE
...() 我在吃饭呢。 Wǒ zài chīfàn ne. I'm eating (right now). RUNNING
V + 拿着筷子。 Ná zhe kuàizi. Holding chopsticks. (state) PERSISTED
V + 我吃了饭。 Wǒ chī le fàn. I ate. (completed) COMPLETED
V + 我吃过寿司。 Wǒ chī guo shòusī. I've eaten sushi (before). EXPERIENCED
Sentence + 我吃饭了。 Wǒ chīfàn le. I've eaten (now). (new state) STATE_CHANGED
/**
 * Chinese Aspect State Machine
 *
 *                    在...呢
 *                  ┌─────────┐
 *                  │ RUNNING  │  (actively executing right now)
 *                  └────┬────┘
 *                       │ action finishes
 *                       ▼
 *  ┌─────────┐    ┌─────────┐    ┌───────────┐
 *  │  IDLE   │───▶│COMPLETED│───▶│EXPERIENCED│
 *  │ (bare)  │ 了 │  (了)   │ 过 │   (过)    │
 *  └─────────┘    └─────────┘    └───────────┘
 *       │                              ▲
 *       │         ┌─────────┐          │
 *       └────────▶│PERSISTED│──────────┘
 *            着   │  (着)   │   (over time, becomes experience)
 *                 └─────────┘
 *
 *  STATE_CHANGED (sentence-final 了): any transition between states
 */

8. Practice — Parse the State

For each sentence, identify the aspect particle and what state it's tracking. Read the Chinese first, then check the breakdown.

// 1. Completed action (了)
我做了作业。
[S:我] [V:做] [ASP:了] [O:作业]
// I.doHomework.completed() → I did my homework.
// 2. Life experience (过)
你去过美国吗?
[S:你] [V:去] [ASP:过] [O:美国] [Q:吗]?
// you.go.experienced("USA")? → Have you ever been to the US?
// 3. Active right now (在...呢)
别打扰他,他在写代码呢。
[IMP:别打扰他] [S:他] [ASP:在] [V:写] [O:代码] [EMPH:呢]
// Don't interrupt him — he.write("code").isRunning()
// Don't bother him, he's writing code!
// 4. Ongoing state (着)
他穿着一件黑色的衣服。
[S:他] [V:穿] [ASP:着] [O:一件黑色的衣服]
// he.wearing = "black_clothes"
// He's wearing black clothes. (state description)
// 5. State change (sentence-final 了)
他们结婚了。
[S:他们] [V:结婚] [ASP:了]
// they.status.changed("married")
// They got married! (state changed from unmarried to married)
// 6. Completed action (了)
她学了三年中文。
[S:她] [V:学] [ASP:了] [DUR:三年] [O:中文]
// she.study.completed(chinese, duration: 3.years)
// She studied Chinese for three years. (completed period)
// 7. Experience (过)
我看过那本书,很好看。
[S:我] [V:看] [ASP:过] [O:那本书]
// I.read.experienced(thatBook) → it was good
// I've read that book — it's good.
// 8. Active right now (在)
你在做什么?我在学中文。
[S:你] [ASP:在] [V:做] [O:什么]? [S:我] [ASP:在] [V:学] [O:中文]。
// you.currentTask.getName()? → I.study("Chinese").isRunning()
// What are you doing? — I'm studying Chinese.
// 9. Ongoing state (着)
外面下着雨。
[P:外面] [V:下] [ASP:着] [O:雨]
// outside.weather.state = "raining"
// It's raining outside. (persistent state — the rain continues)
// 10. State change (了)
我不想吃了。
[S:我] [NEG:不] [V:想] [V2:吃] [ASP:了]
// I.appetite.changed(false)
// I don't want to eat anymore. (state changed — I did want to before)
// 11. Experience, negated (没...过)
我没去过日本。
[S:我] [NEG:没] [V:去] [ASP:过] [O:日本]
// !I.go.experienced("Japan")
// I've never been to Japan. (the experience flag was never set)
// 12. Completed, negated (没 — note: no 了)
他没来。
[S:他] [NEG:没] [V:来]
// !he.come.completed()
// He didn't come. (没 already implies non-completion — 了 drops)
// 13. Active + ongoing state combined
她站着看书。
[S:她] [V:站] [ASP:着] [V2:看] [O:书]
// she.posture.state = "standing"; she.read(book)
// She's standing (着 = state) reading a book.
// 着 here describes the posture state while another action occurs.
// 14. Double 了 (completed action + state change)
我已经吃了饭了。
[S:我] [ADV:已经] [V:吃] [ASP:了] [O:饭] [ASP:了]
// I.eat.completed(food); status.changed("fed")
// I've already eaten. (the eating completed AND my state has changed)
// 15. Tricky: same verb, all four aspects
他跑。         // He runs. (general fact — IDLE)
他在跑。       // He's running. (right now — RUNNING)
他跑了。       // He ran. / He's left! (completed or state change)
他跑过马拉松。  // He's run a marathon. (life experience — EXPERIENCED)
跑着去吧。     // Go by running. (running as ongoing manner — PERSISTED)

State Management Summary

/**
 * Chinese Aspect System v1.0
 *
 * CORE PRINCIPLE:
 * Chinese verbs are IMMUTABLE. They never conjugate.
 * Instead, aspect particles track the STATE of the action.
 *
 * THE FOUR STATE FLAGS:
 *
 * 了 (le)   — .completed() / .changed()
 *   After verb:       action completed    我吃了饭 (I ate)
 *   End of sentence:  state changed       下雨了 (It's raining now)
 *   Negation:         没 + V (了 drops)   我没吃饭 (I didn't eat)
 *
 * 过 (guò)  — .experienced()
 *   After verb:       lifetime experience  我去过中国 (I've been to China)
 *   It's a boolean:   ever done it? yes/no
 *   Negation:         没 + V + 过          我没去过中国 (I've never been)
 *
 * 着 (zhe)  — .ongoing() / state descriptor
 *   After verb:       persistent state     门开着 (The door is open)
 *   NOT active action — it's a property read, not a method call
 *
 * 在 (zài)...呢 (ne)  — .isRunning()
 *   Before verb:      currently executing  我在吃饭 (I'm eating)
 *   Optional 呢:      emphasis             我在吃饭呢 (I'm eating!)
 *
 * DECISION TREE:
 *   Actively happening now?     → 在...呢
 *   Specific action completed?  → V + 了
 *   Ever experienced?           → V + 过
 *   Ongoing state/condition?    → V + 着
 *   Situation just changed?     → sentence + 了
 *   General fact or habit?      → no particle
 *
 * NEXT MODULE: Module 4 — where we wire up more complex
 * sentence patterns with complements and results.
 */

You now understand how Chinese tracks the state of actions without ever mutating a verb. No past tense, no present tense, no future tense — just state flags that tell you whether an action completed, was experienced, is persisting, or is executing right now. It's a state machine, not a timeline. And honestly? It's cleaner than English's approach.

Practice what you learned