C.W.K.
Stream
Lesson 03 of 05 · published

The Python Bridge: Lingua Franca Duo

~9 min · ts-epilogue, python, sibling-quest, bridge

Level 0Curious
0 XP0/93 lessons0/23 achievements
0/100 XP to next level100 XP to go0% complete
"Two languages. One mind. One codebase."

The sibling quest

This Quest was designed as the frontend half of a pair. Python Quest is the backend half. Same shape (17 tracks, ~93 lessons), same goal (become a source-reader of cwkPippa), same voice. Each can be walked independently; the pair is the lingua franca duo.

What translates directly

  • List comprehension ↔ array map/filter. [x*2 for x in arr if x > 0] in Python, arr.filter(x => x > 0).map(x => x*2) in TS. Same operation, different syntax.
  • Type hints ↔ TS annotations. Python's def f(x: int) -> str is function f(x: number): string. The semantics differ (Python's are advisory at runtime; TS's are checked at compile time), but the syntax intent is the same.
  • Protocols ↔ structural typing. Python's typing.Protocol is duck typing made explicit, just like TypeScript's structural matching.
  • Discriminated unions ↔ tagged unions. Same pattern. Python uses Literal types + isinstance / match; TypeScript uses literal types + typeof / switch.
  • async/await. Identical syntax, slightly different semantics (Python's event loop is explicit, JS's is implicit).

What doesn't translate

  • Python has metaclasses; TypeScript doesn't (TC39 decorators are the closest analog).
  • TypeScript has structural typing as the default; Python is nominal-leaning with Protocol opt-in.
  • Python has GIL-bound concurrency; JavaScript has single-threaded event loop.
  • TypeScript has mapped types, conditional types, template literal types; Python's type system is more limited at the type-computation level.
The two languages cover the same problem space with mirrored vocabularies. Once you've walked both quests, you carry one mind across both halves of the codebase. cwkPippa is the proof.

Code

Same pattern — Python·python
# Python — discriminated union with Literal + match.
from typing import Literal

type Shape = (
    dict[Literal['kind'], Literal['circle']] | dict[Literal['kind'], Literal['square']]
)

def area(s):
    match s['kind']:
        case 'circle': return 3.14 * s['radius'] ** 2
        case 'square': return s['side'] ** 2
Same pattern — TypeScript·typescript
// TypeScript — same pattern.
type Shape =
  | { kind: 'circle'; radius: number }
  | { kind: 'square'; side: number };

function area(s: Shape): number {
  switch (s.kind) {
    case 'circle': return Math.PI * s.radius ** 2;
    case 'square': return s.side ** 2;
  }
}

External links

Exercise

Pick a TypeScript pattern from this Quest. Write the equivalent in Python (using Pydantic if it helps). Note which language expresses the pattern more naturally — the answer depends on the specific pattern, and the asymmetries are illuminating.
Hint
Discriminated unions: TS wins. Validation parsing: Python+Pydantic wins. Class-heavy domain models: roughly tied. The two languages aren't superior to each other; they're shaped for different parts of the stack.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.