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
stdlib/Http.affine: typed `Request`/`Response` with assoc-list headers
`[(String, String)]` and `Option<String>` body; `fetch`/`get`/`post`/
`request`/`is_ok`. Effect row `/ { Net, Async }` (reserved built-in
`Net` — cross-module-sound, no per-module effect decl).
Headers are an assoc list, not Dict: lets #160 land independently of
#162 while preserving spine order #160 -> #161 -> #162; upgrade to Dict
later is source-compatible for callers using the helpers.
codegen_deno.ml — general Async-effect lowering (serves the whole
migration spine, not a one-off):
* fd_is_async: a fn whose effect row mentions `Async` is emitted as
`async function` with its body in async context.
* async free-fn calls are awaited at the call site (so
`get(u).status` reads the resolved value, not a Promise).
* __as_httpFetch runtime: assoc-list <-> header object, `Option`
body, `globalThis.fetch` round-trip (explicit `globalThis.` — the
stdlib `fetch` compiles to a module-level `function fetch` that
would otherwise shadow the host).
* http_request extern lowers to `(await __as_httpFetch(...))`.
tests/codegen-deno/http_fetch.{affine,harness.mjs}: e2e via the real
flattened stdlib/Http.affine, `globalThis.fetch` stubbed (no network)
— GET/POST/headers/body/404/is_ok asserted. Full Deno suite + 258-test
gate green (+1 = auto-picked-up AOT Http smoke case).
Also migrates two pre-existing baseline-rot fixtures
(class_basic.affine, ref_fields.affine) from retired `Type { f: x }`
to `Type #{ f: x }` (#218 record syntax; the estate sweep skipped
in-tree test fixtures). Not a #160 change; required to make the Deno
suite green.
Deno-ESM target only here by design; typed-wasm target (the
convergence ABI shared with Ephapax) is tracked as the next slice in
#225. Refs #160 (stays open until both targets land); companion #225.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: docs/guides/migration-playbook.adoc
+38Lines changed: 38 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -164,6 +164,40 @@ The `affinescript compile graph.affine -o graph.onnx` invocation produces a real
164
164
165
165
Why this matters for migration: when porting code that calls platform-specific functions, you do not need to extend AffineScript itself. Declare the platform's API as stubs in your translation unit, and let the backend recognise them. This keeps the frontend small and the backend self-contained.
* The `.catch` umbrella becomes a `match` on `is_ok(resp)` / `resp.status`
185
+
— failure is data, not a detached rejected promise.
186
+
* Headers are an *association list* `[(String, String)]`, not an opaque
187
+
object. Build/read them explicitly. (This will become `Dict` once #162
188
+
lands; the change is source-compatible for callers using the helpers.)
189
+
* The response `body` is raw text. JSON decoding is a *separate* step
190
+
(the #161 `Json` primitive) — do not conflate transport with parsing.
191
+
* Every function that transitively calls `Http` carries `/ { Net, Async }`
192
+
in its signature. That is the point: the network and its asynchrony are
193
+
visible in the type, where ReScript hid them in a `Promise`.
194
+
195
+
Backend status: the Deno-ESM target lowers this to a `globalThis.fetch`
196
+
round-trip (Deno / Node 18+ / browser ESM) and is fully exercised
197
+
end-to-end. The typed-wasm target is a tracked next slice — the
198
+
convergence ABI shared with Ephapax (see <<see-also,Settled Decisions>>,
199
+
typed-wasm ADR-004); AffineScript is not coupled to it.
200
+
167
201
[#decision-criteria]
168
202
== Decision Criteria
169
203
@@ -341,4 +375,8 @@ If you complete a non-trivial `.res → .affine` translation and the re-decompos
341
375
| 1.2
342
376
| 2026-05-02
343
377
| Backend-buildout findings folded into TS→AS index and a new recipe: (1) Float-arithmetic typechecker gap is now closed (no more Int-scaling workaround); (2) `mut`-parameter indexed-write borrow gap is now closed (note the binder-modifier keyword position); (3) new `<<calling-target-intrinsics>>` recipe documents the stub-as-intrinsic pattern that lets user code call CUDA / ONNX / Faust / Verilog runtime ops without extending the language.
378
+
379
+
| 1.3
380
+
| 2026-05-18
381
+
| New `<<portable-http>>` recipe for the C-spine `Http` stdlib primitive (issue #160): ReScript `fetch`/`Js.Promise` → typed `Request`/`Response` with a `/ { Net, Async }` effect row. Deno-ESM target landed and exercised end-to-end; typed-wasm target tracked as the next slice (convergence ABI shared with Ephapax). No existing guidance changed.
0 commit comments