haskell: Phase 15 — IORef (5 ops + module wiring + ioref.sx 13/13 + counter.hs 7/7 + accumulate.hs 8/8)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 53s

hk-bind-data-ioref! registers newIORef / readIORef / writeIORef /
modifyIORef / modifyIORef' under the import alias (default IORef).
Representation: dict {"hk-ioref" true "hk-value" v} allocated inside IO.
modifyIORef' uses hk-deep-force on the new value before write.

Side-effect: fixed pre-existing bug in import handler — modname was
reading (nth d 1) (the qualified flag) instead of (nth d 2). All
'import qualified … as Foo' paths were silently no-ops; map.sx unit
suite jumps from 22→26 passing.

Conformance now 33/34 programs, 266/269 tests (only pre-existing
palindrome.hs 9/12 still failing on string-as-list reversal, present
on prior commit).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-07 18:49:55 +00:00
parent f26f25f146
commit f1fea0f2f1
8 changed files with 379 additions and 21 deletions

View File

@@ -272,19 +272,19 @@ No OCaml changes are needed. The view type is fully representable as an SX dict.
### Phase 15 — IORef
- [ ] `IORef a` representation: a dict `{:hk-ioref true :hk-value v}`.
- [x] `IORef a` representation: a dict `{:hk-ioref true :hk-value v}`.
Allocation creates a new dict in the IO monad. Mutation via `dict-set!`.
- [ ] `newIORef :: a -> IO (IORef a)` — wraps a new dict in `IO`.
- [ ] `readIORef :: IORef a -> IO a` — returns `(IO (get ref ":hk-value"))`.
- [ ] `writeIORef :: IORef a -> a -> IO ()` — `(dict-set! ref ":hk-value" v)`,
- [x] `newIORef :: a -> IO (IORef a)` — wraps a new dict in `IO`.
- [x] `readIORef :: IORef a -> IO a` — returns `(IO (get ref ":hk-value"))`.
- [x] `writeIORef :: IORef a -> a -> IO ()` — `(dict-set! ref ":hk-value" v)`,
returns `(IO ("Tuple"))`.
- [ ] `modifyIORef :: IORef a -> (a -> a) -> IO ()` — read + apply + write.
- [ ] `modifyIORef' :: IORef a -> (a -> a) -> IO ()` — strict variant (force
- [x] `modifyIORef :: IORef a -> (a -> a) -> IO ()` — read + apply + write.
- [x] `modifyIORef' :: IORef a -> (a -> a) -> IO ()` — strict variant (force
new value before write).
- [ ] `Data.IORef` module wiring.
- [ ] Tests in `lib/haskell/tests/ioref.sx` (≥ 10 tests: new+read, write,
- [x] `Data.IORef` module wiring.
- [x] Tests in `lib/haskell/tests/ioref.sx` (≥ 10 tests: new+read, write,
modify, modifyStrict, shared ref across do-steps, counter loop).
- [ ] Conformance programs:
- [x] Conformance programs:
- `counter.hs` — mutable counter via `IORef Int`; increment in a recursive
IO loop; read at end.
- `accumulate.hs` — accumulate results into `IORef [Int]` inside a mapped
@@ -315,6 +315,17 @@ No OCaml changes are needed. The view type is fully representable as an SX dict.
_Newest first._
**2026-05-07** — Phase 15 IORef complete (5 ops + module wiring + 13 unit
tests + 2 conformance programs). `hk-bind-data-ioref!` in `eval.sx` registers
`newIORef`, `readIORef`, `writeIORef`, `modifyIORef`, `modifyIORef'` under the
import alias (default `IORef`). Representation: dict `{"hk-ioref" true
"hk-value" v}` allocated inside `IO`. Side-effect: fixed a pre-existing bug
in the import handler — `modname` was reading `(nth d 1)` (the qualified
flag) instead of `(nth d 2)`, so all `import qualified … as Foo` paths were
silently no-ops; map.sx unit suite jumps from 22→26 passing as a result.
Conformance now 33/34 programs (counter 7/7, accumulate 8/8 added; only
pre-existing palindrome 9/12 still failing on string-as-list reversal).
**2026-05-07** — Phase 14 conformance: person.hs (7/7) + config.hs (10/10) → Phase 14 complete:
- `program-person.sx`: classic Person record with `birthday p = p { age = age p + 1 }`
exercising the read-then-update idiom on a CAF instance, plus `deriving Show`