You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
briefs/2.2.0-remaining-issues.md: status item #1 flipped to done
with summary of what landed; detailed #82 section rewritten as a
DONE summary mirroring the #35 entry; "Recommendation for next
slot" updated to point at #80 (with the design-pass caveat) since
#83 is explicitly do-last. Added a new "Fleet-wide follow-ups"
section noting the deferred coverage.run.omit and dev-deps-via-pdm
sweeps so the next session can pick them up.
CHANGELOG.md: added Internal entries for the doc additions and the
revived test. The continuations behaviour itself is unchanged; what
changed is the documentation and the test coverage of an existing
property.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: CHANGELOG.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -25,6 +25,8 @@
25
25
26
26
-`unpythonic.llist.cons`: dropped the internal `_immutable` sentinel; the read-only `car`/`cdr` are now installed via `object.__setattr__` in `__init__`, and `__setattr__` is a one-liner that always raises.
27
27
-`unpythonic.env.env`: dropped the `_direct_write` whitelist that allowed internal slots (`_env`, `_finalized`) to bypass `__setattr__`. Internal initialisation and `finalize()` now use `object.__setattr__` directly. Client code attempting `e._env = ...` or `e._finalized = ...` is now rejected by the reserved-name check (was silently allowed via the whitelist).
28
+
-`doc/macros.md`: new "Topology of continuations: how the wiring works" subsection (with inlined `callcc_topology.png` diagram explaining the `cc`/`pcc` machinery) and "Scoping of locals in continuations" subsection (the rule, the box workaround, the three load-bearing limits that ruled out auto-`nonlocal` propagation). Closes #82.
29
+
-`unpythonic/syntax/tests/test_conts.py`: revived the `"scoping, in presence of nonlocal"` testset that was disabled in 2022 due to a coverage.py source-parsing limitation. The new `[tool.coverage.run]` config in `pyproject.toml` scopes coverage to production code (excluding `*/tests/*`) and sidesteps the parse failure at report time.
## #82 — Document scoping of locals in continuations
42
68
43
-
**Decision: docs only, do not fix.** Per the ticket comments
44
-
(Technologicat, 2022), implementation was tried (commit `2c7477c`,
45
-
propagating parent-scope declarations into the continuation) but ran
46
-
into three load-bearing limits:
47
-
48
-
- Continuation parameters (assignment targets of `call_cc`) must shadow
49
-
same-named names from the parent scope.
50
-
- No propagation upward — a name declared inside a continuation can't
51
-
become available to the parent context, even though source-wise
52
-
they're the same function. Would need a second pass.
53
-
- At the top of a `with continuations` block, you can't tell from the
54
-
AST whether the block is inside a function (so `nonlocal` vs `global`
55
-
for parent locals is undecidable without whole-module analysis).
56
-
57
-
Therefore: continuations introduce a scope boundary. Document this
58
-
analogously to how Python's comprehensions and generator expressions do.
59
-
60
-
**Resume notes (added 2026-05-05)**:
61
-
62
-
- The original experiment lives at commit `2c7477c` — recover via git
63
-
archaeology (`git show 2c7477c`, `git diff 2c7477c~1 2c7477c` for the
64
-
shape of the change). The half-finished propagation logic and any
65
-
failing-test commits around it are the clearest source of the *why*.
66
-
- There's an SVG/PDF illustration in the repo somewhere (predates this
67
-
session) that maps the scoping situation; needs locating and
68
-
deciphering to fold into the docs. Worth a `find . -name '*.svg'`
69
-
/ `*.pdf` and a look at anything in `doc/` that isn't already
70
-
cross-referenced from `macros.md`.
71
-
- Continuations are one of the most complex features in unpythonic.
72
-
Plan: either a dedicated subsection in `doc/macros.md` near the
73
-
existing continuations material, or a standalone `doc/continuations.md`
74
-
linked from there.
75
-
- The compiled-out experimental code in `unpythonic/syntax/tailtools.py`
76
-
(mentioned in the original ticket) is half of the *why* — the other
77
-
half is the ticket comment thread. Both need to make it into the doc
78
-
in present-tense form.
79
-
80
-
Touchpoints (when ready):
81
-
-**Where to write**: `doc/macros.md` continuations section, or new
82
-
`doc/continuations.md`.
83
-
-**Updated examples**: `unpythonic/syntax/tests/test_conts.py`, near
84
-
end of file (per ticket as of `f772df4`).
85
-
86
-
Save for its own session — the writing is more careful than the code.
69
+
**DONE this session.**
70
+
71
+
-`doc/macros.md`: new `#### Topology of continuations: how the wiring works` subsection with inlined `callcc_topology.png` diagram, walking through the five panels (Base case, Sequence, Nested, Confetti chaining rule, Tail-call composition) and explaining what `cc` and `pcc` are, who sets them, and how the chain unwinds when a function ends or tail-calls another. Followed by `#### Scoping of locals in continuations` covering the rule (each `call_cc[]` introduces a scope boundary), the box workaround, and the three load-bearing limits that ruled out auto-`nonlocal` propagation. TOC updated.
72
+
-`doc/callcc_topology.svg` re-exported with a white background (xviewer's checkerboard fallback made the transparent original unreadable); PNG export added.
73
+
-`unpythonic/syntax/tests/test_conts.py`: revived the `"scoping, in presence of nonlocal"` testset (disabled in 2022 due to a coverage.py source-parsing issue). The test demonstrates that `nonlocal x` inside a continuation reaches back to the parent's `x`, just as in any ordinary nested closure. Ruff F811 silenced at the use site (post-macro the `nonlocal` is at the top of a separate function, so it isn't actually a redefinition).
74
+
-`pyproject.toml`: new `[tool.coverage.run]` section scopes coverage to production code (`source = ["unpythonic"]`) and excludes `*/tests/*`. Sidesteps the coverage.py parse failure on the revived test at `coverage xml` time, and aligns with general "coverage signal is about production code, not tests" hygiene. Pattern documented in `~/.claude/CI-SETUP-NOTES.md` §4a for fleet propagation.
75
+
- Bonus: `shift`/`reset` attribution corrected in the delimited-continuation parenthetical (Danvy & Filinski 1990, not Felleisen — Felleisen's operators are `control`/`prompt`) with links to Wikipedia and the Racket reference.
0 commit comments