Skip to content

Commit dcfb2b5

Browse files
Technologicatclaude
andcommitted
D13 followup: re-enable monadic_do[List] Pythagorean test in Pytkell
D17 wasn't actually a deferred issue — the transient failure I recorded mid-session disappeared once the `List._make = from_iterable` hook was in place. That hook lets `mogrify` reconstruct the container elementwise (via `cls._make(generator)`, matching the namedtuple convention) instead of the varargs fallback `cls(generator)` that wraps the whole generator as a single element. The same hook fixed `forall` Pythagorean triples under Pytkell — same root cause. Re-enabling the classical Pythagorean-triples-under-Pytkell test in the "monadic do-notation" testset (now 5/5) and removing the stale D17 entry from TODO_DEFERRED.md. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 8d3feb4 commit dcfb2b5

2 files changed

Lines changed: 12 additions & 7 deletions

File tree

TODO_DEFERRED.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,5 @@ Next unused item code: D16
5757
- **D16: Remove `unpythonic.amb.MonadicList` alias (3.0.0)**: As part of D13 monads port, `MonadicList` was moved to `unpythonic.monads.List` with a varargs constructor (`List(1, 2, 3)` instead of `MonadicList([1, 2, 3])`). A silent alias `MonadicList = List` is kept in `unpythonic/amb.py` for backward-name compatibility during the 2.x series. Remove the alias in 3.0.0 along with the accompanying `TODO(3.0.0)` comment at the alias site. Users must then import `List` directly from `unpythonic.monads`. Note: this is name-only compat — the constructor signature changed at 2.0.0, so existing callers of `MonadicList([...])` already needed to switch to varargs or `from_iterable(...)` at 2.0.0. (Noted 2026-04-17.)
5858

5959

60-
- **D17: `monadic_do[List]` inside Pytkell's auto-lazify yields wrapped generators**: The Pythagorean-triples-style `monadic_do[List]` computation, when run under the Pytkell dialect (which wraps the whole module in `with lazify, autocurry:`), produces a result whose `tuple(sorted(pt))` is a 1-tuple containing a generator instead of the expected 6-tuple of triples. The `_make = from_iterable` hook on `List` (added to make `mogrify` rebuild the container elementwise) fixed the analogous `forall`-based test and the container-monad cases (`Maybe`, `Writer`, `Either` under Pytkell work fine), but something in the deeper bind-chain recursion under `lazify`'s `mogrify` still produces a generator that doesn't get forced. Workaround for now: use `monadic_do[List]` outside Pytkell, or materialize intermediate results explicitly. Debug starting point: `unpythonic/dialects/tests/test_pytkell.py`, the commented-out List-Pythagorean case in the "monadic do-notation" testset. (Noted 2026-04-17.)
6160

6261

unpythonic/dialects/tests/test_pytkell.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
from ...syntax import macros, continuations, call_cc, tco # noqa: F401, F811
1111
from ...syntax import macros, monadic_do # noqa: F401, F811
12-
from ...monads import Maybe, Writer
12+
from ...monads import Maybe, Writer, List
1313
from ...funutil import Values
1414
from ...misc import timer
1515

@@ -256,11 +256,17 @@ def maybe_sqrt(x):
256256
b := maybe_sqrt(a)] in bad << Maybe(b)
257257
test[bad == Maybe(nil)] # noqa: F821 -- `nil` is in the Pytkell dialect
258258

259-
# List-monad Pythagorean triples under Pytkell's auto-lazify is deferred:
260-
# `lazify`'s deep-force via `mogrify` doesn't reliably unwrap the nested
261-
# generator expressions that `List`'s internal `from_iterable` produces
262-
# during bind. Use `monadic_do[List]` outside Pytkell, or materialize
263-
# intermediate results explicitly. See TODO_DEFERRED entry.
259+
# List — classical Pythagorean triples.
260+
def r(lo, hi):
261+
return List.from_iterable(range(lo, hi))
262+
263+
with monadic_do[List] as pt:
264+
[z := r(1, 21),
265+
x := r(1, z + 1),
266+
y := r(x, z + 1),
267+
_ := List.guard(x * x + y * y == z * z)] in pt << List((x, y, z))
268+
test[tuple(sorted(pt)) == ((3, 4, 5), (5, 12, 13), (6, 8, 10),
269+
(8, 15, 17), (9, 12, 15), (12, 16, 20))]
264270

265271
# Writer — logged computation.
266272
with monadic_do[Writer] as w:

0 commit comments

Comments
 (0)