OCaml bootstrapper Phase 2: HTML renderer, SX server, Python bridge

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-15 23:28:48 +00:00
parent 16fa813d6d
commit 313f7d6be1
18 changed files with 2541 additions and 191 deletions

View File

@@ -148,6 +148,21 @@ def create_app() -> "Quart":
target = path + "/" + ("?" + qs if qs else "")
return redirect(target, 301)
@app.get("/sx/_engine")
async def sx_engine_info():
"""Diagnostic: which SX engine is active."""
import os, json
info = {"engine": "python-ref", "ocaml": False}
if os.environ.get("SX_USE_OCAML") == "1":
try:
from shared.sx.ocaml_bridge import get_bridge
bridge = await get_bridge()
engine = await bridge.ping()
info = {"engine": engine, "ocaml": True, "pid": bridge._proc.pid}
except Exception as e:
info = {"engine": "ocaml-error", "ocaml": False, "error": str(e)}
return json.dumps(info), 200, {"Content-Type": "application/json"}
@app.get("/sx/")
async def sx_home():
"""SX docs home page."""

View File

@@ -231,15 +231,135 @@
(tr (td :class "pr-4 py-1" "3")
(td :class "pr-4" "Content-addressed computation")
(td :class "text-emerald-600 font-semibold" "\u2714 Done \u2014 content-hash, freeze-to-cid, thaw-from-cid"))
(tr (td :class "pr-4 py-1" "3.5")
(td :class "pr-4" "Data representations")
(td :class "text-stone-400" "Planned — byte buffers + typed structs"))
(tr (td :class "pr-4 py-1" "4")
(td :class "pr-4" "Concurrent CEK")
(td :class "text-amber-600 font-semibold" "Spec complete \u2014 implementation next"))
(td :class "text-amber-600 font-semibold" "Spec complete implementation next"))
(tr (td :class "pr-4 py-1" "5")
(td :class "pr-4" "Linear effects")
(td :class "text-stone-400" "Future")))))
;; -----------------------------------------------------------------------
;; Step 4: Concurrent CEK \u2014 deep spec
;; Step 3.5: Data Representations
;; -----------------------------------------------------------------------
(h2 :class "text-xl font-bold mt-12 mb-4" "Step 3.5: Data Representations")
(p "Two primitives that sit below concurrency but above the raw CEK machine. "
"Both are about how values are represented — enabling work that's currently host-only.")
(h3 :class "text-lg font-semibold mt-8 mb-3" "3.5a Byte Buffers")
(p "Fixed-size mutable byte arrays. A small primitive surface that unlocks "
"binary protocol parsing, image headers, wire formats, and efficient CID computation:")
(~docs/code :code
(str ";; Create and write\n"
"(let ((buf (make-buffer 256)))\n"
" (buffer-write-u8! buf 0 #xFF)\n"
" (buffer-write-u32! buf 1 magic-number)\n"
" (buffer-slice buf 0 5))\n"
"\n"
";; Read from network/file\n"
"(let ((header (buffer-slice packet 0 12)))\n"
" (case (buffer-read-u8 header 0)\n"
" (1 (parse-handshake header))\n"
" (2 (parse-data header))\n"
" (else (error \"unknown packet type\"))))"))
(p "Primitives:")
(ul :class "list-disc pl-6 mb-4 space-y-1"
(li (code "make-buffer") " — allocate N zero-filled bytes")
(li (code "buffer-read-u8/u16/u32") ", " (code "buffer-read-i8/i16/i32") " — typed reads at offset")
(li (code "buffer-write-u8!/u16!/u32!") " — typed writes at offset (big-endian default)")
(li (code "buffer-slice") " — zero-copy view of a region")
(li (code "buffer-length") " — byte count")
(li (code "buffer->list") ", " (code "list->buffer") " — conversion to/from byte lists")
(li (code "buffer->string") ", " (code "string->buffer") " — UTF-8 encode/decode"))
(p "Host mapping:")
(div :class "overflow-x-auto mb-6"
(table :class "min-w-full text-sm"
(thead (tr
(th :class "text-left pr-4 pb-2 font-semibold" "Primitive")
(th :class "text-left pr-4 pb-2 font-semibold" "JavaScript")
(th :class "text-left pr-4 pb-2 font-semibold" "Python")
(th :class "text-left pb-2 font-semibold" "OCaml")))
(tbody
(tr (td :class "pr-4 py-1 font-mono" "make-buffer")
(td :class "pr-4" "new ArrayBuffer(n)")
(td :class "pr-4" "bytearray(n)")
(td "Bytes.create n"))
(tr (td :class "pr-4 py-1 font-mono" "buffer-read-u32")
(td :class "pr-4" "DataView.getUint32")
(td :class "pr-4" "struct.unpack_from")
(td "Bytes.get_int32_be"))
(tr (td :class "pr-4 py-1 font-mono" "buffer-slice")
(td :class "pr-4" "new Uint8Array(buf, off, len)")
(td :class "pr-4" "memoryview(buf)[off:off+len]")
(td "Bytes.sub buf off len")))))
(p "Byte buffers connect directly to content addressing (Step 3). "
"Computing a CID currently requires host-side hashing of opaque SX text. "
"With buffers, the hash input can be a canonical binary representation — "
"deterministic, compact, and consistent across hosts.")
(h3 :class "text-lg font-semibold mt-8 mb-3" "3.5b Typed Structs")
(p "Named product types with fixed fields. On interpreted hosts, structs are syntactic sugar over dicts. "
"On compiled hosts (OCaml, Rust), they compile to unboxed records — no dict overhead, "
"no hash lookups, no string key comparisons:")
(~docs/code :code
(str ";; Define a struct\n"
"(defstruct point (x : number) (y : number))\n"
"\n"
";; Construct\n"
"(let ((p (make-point 3 4)))\n"
" ;; Access — compiles to field offset on native hosts\n"
" (+ (point-x p) (point-y p))) ;; => 7\n"
"\n"
";; Pattern match\n"
"(case p\n"
" ((point x y) (sqrt (+ (* x x) (* y y))))) ;; => 5"))
(p "What " (code "defstruct") " generates:")
(ul :class "list-disc pl-6 mb-4 space-y-1"
(li (code "make-point") " — constructor (arity-checked)")
(li (code "point?") " — type predicate")
(li (code "point-x") ", " (code "point-y") " — field accessors")
(li (code "point") " — case pattern for destructuring"))
(p "The performance difference matters for compiled hosts:")
(div :class "overflow-x-auto mb-6"
(table :class "min-w-full text-sm"
(thead (tr
(th :class "text-left pr-4 pb-2 font-semibold" "Operation")
(th :class "text-left pr-4 pb-2 font-semibold" "Dict (current)")
(th :class "text-left pb-2 font-semibold" "Struct (compiled)")))
(tbody
(tr (td :class "pr-4 py-1" "Field access")
(td :class "pr-4" "Hash lookup — O(1) amortized, cache-unfriendly")
(td "Offset load — O(1) actual, single instruction"))
(tr (td :class "pr-4 py-1" "Construction")
(td :class "pr-4" "Allocate hash table + insert N entries")
(td "Allocate N words, write sequentially"))
(tr (td :class "pr-4 py-1" "Pattern match")
(td :class "pr-4" "N string comparisons")
(td "Tag check + field projection")))))
(p "Typed structs connect to the gradual type system in " (code "types.sx") ". "
"A " (code "defstruct") " declaration is a type definition that the type checker can verify "
"and the compiler can exploit. On interpreted hosts, the same code runs — just slower.")
;; -----------------------------------------------------------------------
;; Step 4: Concurrent CEK — deep spec
;; -----------------------------------------------------------------------
(h2 :class "text-xl font-bold mt-12 mb-4" "Step 4: Concurrent CEK")
@@ -449,33 +569,33 @@
(th :class "text-left pr-4 pb-2 font-semibold" "Primitive")
(th :class "text-left pr-4 pb-2 font-semibold" "JavaScript")
(th :class "text-left pr-4 pb-2 font-semibold" "Python")
(th :class "text-left pr-4 pb-2 font-semibold" "Haskell")
(th :class "text-left pr-4 pb-2 font-semibold" "OCaml")
(th :class "text-left pb-2 font-semibold" "Rust/WASM")))
(tbody
(tr (td :class "pr-4 py-1 font-mono" "spawn")
(td :class "pr-4" "Web Worker")
(td :class "pr-4" "asyncio.create_task")
(td :class "pr-4" "forkIO")
(td :class "pr-4" "Eio.Fiber.fork")
(td "tokio::spawn"))
(tr (td :class "pr-4 py-1 font-mono" "channel")
(td :class "pr-4" "MessageChannel")
(td :class "pr-4" "asyncio.Queue")
(td :class "pr-4" "TChan (STM)")
(td :class "pr-4" "Eio.Stream.t")
(td "mpsc::channel"))
(tr (td :class "pr-4 py-1 font-mono" "yield!")
(td :class "pr-4" "setTimeout(0)")
(td :class "pr-4" "await asyncio.sleep(0)")
(td :class "pr-4" "threadDelay 0")
(td :class "pr-4" "Eio.Fiber.yield")
(td "tokio::task::yield_now"))
(tr (td :class "pr-4 py-1 font-mono" "freeze/thaw")
(td :class "pr-4" "postMessage + JSON")
(td :class "pr-4" "pickle / SX text")
(td :class "pr-4" "Serialise + SX text")
(td :class "pr-4" "Marshal + SX text")
(td "serde + SX text"))
(tr (td :class "pr-4 py-1 font-mono" "select")
(td :class "pr-4" "Promise.race")
(td :class "pr-4" "asyncio.wait FIRST_COMPLETED")
(td :class "pr-4" "STM orElse")
(td :class "pr-4" "Eio.Fiber.any")
(td "tokio::select!")))))
(h3 :class "text-lg font-semibold mt-8 mb-3" "4.7 Roadmap")
@@ -501,9 +621,9 @@
(td :class "pr-4" "JavaScript")
(td "Art DAG integration path"))
(tr (td :class "pr-4 py-1" "4d")
(td :class "pr-4" "Haskell bootstrapper")
(td :class "pr-4" "Haskell")
(td "Spec portability, native concurrency"))
(td :class "pr-4" "OCaml bootstrapper → native compilation")
(td :class "pr-4" "OCaml")
(td "Native performance, direct CEK-to-ML mapping"))
(tr (td :class "pr-4 py-1" "4e")
(td :class "pr-4" "Rust/WASM bootstrapper")
(td :class "pr-4" "Rust")
@@ -526,8 +646,8 @@
(td "Resource safety, exactly-once delivery")))))
(p "Each phase is independently valuable. Phase 4a (Web Worker spawn) is the immediate next build. "
"Phase 4d (Haskell) proves the spec is truly host-independent. "
"Phase 4e (Rust/WASM) proves it can be fast. "
"Phase 4d (OCaml) proves the spec compiles to native code — the CEK machine maps directly to ML's runtime model. "
"Phase 4e (Rust/WASM) proves it can run in the browser at near-native speed. "
"Phase 4g (IPFS) makes it distributed.")
;; -----------------------------------------------------------------------