Phase 4: Eliminate nested CEK from HO form handlers
Higher-order forms (map, filter, reduce, some, every?, for-each, map-indexed) now evaluate their arguments via CEK frames instead of nested trampoline(eval-expr(...)) calls. Added HoSetupFrame — staged evaluation of HO form arguments. When all args are evaluated, ho-setup-dispatch sets up the iteration frame. This keeps a single linear CEK continuation chain instead of spawning nested CEK instances. 14 nested eval-expr calls eliminated (39 → 25 remaining). The remaining 25 are in delegate functions (sf-letrec, sf-scope, parse-keyword-args, qq-expand, etc.) called infrequently. All tests unchanged: JS 747/747, Full 864/870, Python 679/679. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -246,7 +246,11 @@
|
||||
(dict :label "Reactive Runtime" :href "/sx/(etc.(plan.reactive-runtime))"
|
||||
:summary "Seven feature layers — ref, foreign FFI, state machines, commands with undo/redo, render loops, keyed lists, client-first app shell. Zero new platform primitives.")
|
||||
(dict :label "Rust/WASM Host" :href "/sx/(etc.(plan.rust-wasm-host))"
|
||||
:summary "Bootstrap the SX spec to Rust, compile to WASM, replace sx-browser.js. Shared platform layer for DOM, phased rollout from parse to full parity.")))
|
||||
:summary "Bootstrap the SX spec to Rust, compile to WASM, replace sx-browser.js. Shared platform layer for DOM, phased rollout from parse to full parity.")
|
||||
(dict :label "Isolated Evaluator" :href "/sx/(etc.(plan.isolated-evaluator))"
|
||||
:summary "Core/application split, shared sx-platform.js, isolated JS evaluator, Rust WASM via handle table. Only language-defining spec gets bootstrapped; everything else is runtime-evaluated .sx.")
|
||||
(dict :label "Mother Language" :href "/sx/(etc.(plan.mother-language))"
|
||||
:summary "SX as its own compiler. OCaml as substrate (closest to CEK), Koka as alternative (compile-time linearity), ultimately self-hosting. One language, every target.")))
|
||||
|
||||
(define reactive-islands-nav-items (list
|
||||
(dict :label "Overview" :href "/sx/(geography.(reactive))"
|
||||
|
||||
450
sx/sx/plans/mother-language.sx
Normal file
450
sx/sx/plans/mother-language.sx
Normal file
@@ -0,0 +1,450 @@
|
||||
;; ---------------------------------------------------------------------------
|
||||
;; Mother Language — SX as its own compiler, OCaml as the substrate
|
||||
;; ---------------------------------------------------------------------------
|
||||
|
||||
(defcomp ~plans/mother-language/plan-mother-language-content ()
|
||||
(~docs/page :title "Mother Language"
|
||||
|
||||
(p :class "text-stone-500 text-sm italic mb-8"
|
||||
"The ideal language for evaluating the SX core spec is SX itself. "
|
||||
"The path: OCaml as the initial substrate (closest existing language to what CEK is), "
|
||||
"Koka as an alternative (compile-time linearity), ultimately a self-hosting SX compiler "
|
||||
"that emits machine code directly from the spec. One language. Every target.")
|
||||
|
||||
|
||||
;; -----------------------------------------------------------------------
|
||||
;; The argument
|
||||
;; -----------------------------------------------------------------------
|
||||
|
||||
(~docs/section :title "The Argument" :id "argument"
|
||||
|
||||
(h4 :class "font-semibold mt-4 mb-2" "What the evaluator actually does")
|
||||
(p "The CEK machine is a " (code "state \u2192 state") " loop over sum types. "
|
||||
"Each step pattern-matches on the Control register, consults the Environment, "
|
||||
"and transforms the Kontinuation. Every SX expression, every component render, "
|
||||
"every signal update goes through this loop. It's the hot path.")
|
||||
(p "The ideal host language is one where this loop compiles to a tight jump table "
|
||||
"with minimal allocation. That means: algebraic types, pattern matching, "
|
||||
"persistent data structures, and a native effect system.")
|
||||
|
||||
(h4 :class "font-semibold mt-6 mb-2" "Why multiple hosts is the wrong goal")
|
||||
(p "The current architecture bootstraps the spec to Python, JavaScript, and Rust. "
|
||||
"Each host has impedance mismatches:")
|
||||
(ul :class "list-disc list-inside space-y-1 mt-2"
|
||||
(li (strong "Python") " \u2014 slow. Tree-walk overhead is 100\u20131000x vs native. "
|
||||
"The async adapter is complex because Python's async model is cooperative, not effect-based.")
|
||||
(li (strong "JavaScript") " \u2014 no sum types, prototype-based dispatch, GC pauses unpredictable. "
|
||||
"The bootstrapper works around JS limitations rather than mapping naturally.")
|
||||
(li (strong "Rust") " \u2014 ownership fights shared immutable trees. Every " (code "Rc<Vec<Value>>")
|
||||
" is overhead. Closures capturing environments need " (code "Arc") " gymnastics."))
|
||||
(p "Each host makes the evaluator work, but none make it " (em "natural") ". "
|
||||
"The translation is structure-" (em "creating") ", not structure-" (em "preserving") ".")
|
||||
|
||||
(h4 :class "font-semibold mt-6 mb-2" "The Mother Language is SX")
|
||||
(p "The spec defines the semantics. The CEK machine is the most explicit form of those semantics. "
|
||||
"The ideal \"language\" is one that maps 1:1 onto CEK transitions and compiles them to "
|
||||
"optimal machine code. That language is SX itself \u2014 compiled, not interpreted.")
|
||||
(p "The hosts (Python, JS, Haskell, Rust) become " (em "platform layers") " \u2014 "
|
||||
"they provide IO, DOM, database, GPU access. The evaluator itself is always the same "
|
||||
"compiled SX core, embedded as a native library or WASM module."))
|
||||
|
||||
|
||||
;; -----------------------------------------------------------------------
|
||||
;; Why OCaml
|
||||
;; -----------------------------------------------------------------------
|
||||
|
||||
(~docs/section :title "Why OCaml" :id "ocaml"
|
||||
|
||||
(p "OCaml is the closest existing language to what the CEK machine is. "
|
||||
"The translation from " (code "cek.sx") " to OCaml is nearly mechanical.")
|
||||
|
||||
(h4 :class "font-semibold mt-4 mb-2" "Natural mapping")
|
||||
(div :class "overflow-x-auto rounded border border-stone-200 mb-4"
|
||||
(table :class "w-full text-left text-sm"
|
||||
(thead (tr :class "border-b border-stone-200 bg-stone-100"
|
||||
(th :class "px-3 py-2 font-medium text-stone-600" "SX concept")
|
||||
(th :class "px-3 py-2 font-medium text-stone-600" "OCaml primitive")
|
||||
(th :class "px-3 py-2 font-medium text-stone-600" "Notes")))
|
||||
(tbody
|
||||
(tr :class "border-b border-stone-100"
|
||||
(td :class "px-3 py-2 text-stone-700" "Value (Nil | Num | Str | List | ...)")
|
||||
(td :class "px-3 py-2 text-stone-700" "Algebraic variant type")
|
||||
(td :class "px-3 py-2 text-stone-600" "Direct mapping, no boxing"))
|
||||
(tr :class "border-b border-stone-100"
|
||||
(td :class "px-3 py-2 text-stone-700" "Frame (IfFrame | ArgFrame | MapFrame | ...)")
|
||||
(td :class "px-3 py-2 text-stone-700" "Algebraic variant type")
|
||||
(td :class "px-3 py-2 text-stone-600" "20+ variants, pattern match dispatch"))
|
||||
(tr :class "border-b border-stone-100"
|
||||
(td :class "px-3 py-2 text-stone-700" "Environment (persistent map)")
|
||||
(td :class "px-3 py-2 text-stone-700" (code "Map.S"))
|
||||
(td :class "px-3 py-2 text-stone-600" "Built-in balanced tree, structural sharing"))
|
||||
(tr :class "border-b border-stone-100"
|
||||
(td :class "px-3 py-2 text-stone-700" "Continuation (list of frames)")
|
||||
(td :class "px-3 py-2 text-stone-700" "Immutable list")
|
||||
(td :class "px-3 py-2 text-stone-600" "cons/match, O(1) push/pop"))
|
||||
(tr :class "border-b border-stone-100"
|
||||
(td :class "px-3 py-2 text-stone-700" "cek-step (pattern match on C)")
|
||||
(td :class "px-3 py-2 text-stone-700" (code "match") " expression")
|
||||
(td :class "px-3 py-2 text-stone-600" "Compiles to jump table"))
|
||||
(tr :class "border-b border-stone-100"
|
||||
(td :class "px-3 py-2 text-stone-700" "shift/reset")
|
||||
(td :class "px-3 py-2 text-stone-700" (code "perform") " / " (code "continue"))
|
||||
(td :class "px-3 py-2 text-stone-600" "Native in OCaml 5"))
|
||||
(tr :class "border-b border-stone-100"
|
||||
(td :class "px-3 py-2 text-stone-700" "Concurrent CEK (fibers)")
|
||||
(td :class "px-3 py-2 text-stone-700" "Domains + effect handlers")
|
||||
(td :class "px-3 py-2 text-stone-600" "One fiber per CEK machine"))
|
||||
(tr
|
||||
(td :class "px-3 py-2 text-stone-700" "Linear continuations")
|
||||
(td :class "px-3 py-2 text-stone-700" "One-shot continuations (default)")
|
||||
(td :class "px-3 py-2 text-stone-600" "Runtime-enforced, not compile-time")))))
|
||||
|
||||
(h4 :class "font-semibold mt-4 mb-2" "Compilation targets")
|
||||
(ul :class "list-disc list-inside space-y-1 mt-2"
|
||||
(li (strong "Native") " \u2014 OCaml's native compiler produces fast binaries, small footprint. "
|
||||
"Embed in Python via C ABI (ctypes/cffi). Embed in Node via N-API.")
|
||||
(li (strong "WASM") " \u2014 " (code "wasm_of_ocaml") " is mature (used by Facebook's Flow/Reason). "
|
||||
"Produces compact " (code ".wasm") " modules. Loaded via " (code "sx-platform.js") " like the Rust WASM plan.")
|
||||
(li (strong "JavaScript") " \u2014 " (code "js_of_ocaml") " for legacy browser targets. "
|
||||
"Falls back to JS when WASM isn't available."))
|
||||
|
||||
(h4 :class "font-semibold mt-4 mb-2" "What OCaml replaces")
|
||||
(p "The Haskell and Rust evaluator implementations become unnecessary. "
|
||||
"OCaml covers both server (native) and client (WASM) from one codebase. "
|
||||
"The sx-haskell and sx-rust work proved the spec is host-independent \u2014 "
|
||||
"OCaml is the convergence point.")
|
||||
(p "Python and JavaScript evaluators remain as " (em "platform layers") " \u2014 "
|
||||
"they provide IO primitives, not evaluation logic. The Python web framework calls "
|
||||
"the OCaml evaluator via FFI for rendering. The browser loads the WASM evaluator "
|
||||
"and connects it to " (code "sx-platform.js") " for DOM access."))
|
||||
|
||||
|
||||
;; -----------------------------------------------------------------------
|
||||
;; Koka as alternative
|
||||
;; -----------------------------------------------------------------------
|
||||
|
||||
(~docs/section :title "Koka as Alternative" :id "koka"
|
||||
|
||||
(p "Koka (Daan Leijen, MSR) addresses OCaml's one weakness: "
|
||||
(strong "compile-time linearity") ".")
|
||||
|
||||
(h4 :class "font-semibold mt-4 mb-2" "Where Koka wins")
|
||||
(ul :class "list-disc list-inside space-y-2 mt-2"
|
||||
(li (strong "Perceus reference counting") " \u2014 the compiler tracks which values are used linearly. "
|
||||
"Linear values are mutated in-place (zero allocation). "
|
||||
"Non-linear values use reference counting (no GC at all).")
|
||||
(li (strong "Effect types") " \u2014 effects are tracked in the type system. "
|
||||
"A function's type says exactly which effects it can perform. "
|
||||
"The type checker enforces that handlers exist for every effect.")
|
||||
(li (strong "One-shot continuations by default") " \u2014 like OCaml 5, but " (em "statically enforced") ". "
|
||||
"The type system prevents invoking a linear continuation twice. "
|
||||
"No runtime check needed."))
|
||||
|
||||
(h4 :class "font-semibold mt-4 mb-2" "Where Koka is weaker")
|
||||
(ul :class "list-disc list-inside space-y-2 mt-2"
|
||||
(li (strong "Maturity") " \u2014 research language. Smaller ecosystem, fewer FFI bindings, "
|
||||
"less battle-tested than OCaml.")
|
||||
(li (strong "WASM backend") " \u2014 compiles to C \u2192 WASM (via Emscripten). "
|
||||
"Works but less optimized than " (code "wasm_of_ocaml") " or Rust's " (code "wasm-pack") ".")
|
||||
(li (strong "Embeddability") " \u2014 C FFI works but less established for Python/Node embedding."))
|
||||
|
||||
(p "Koka is the right choice " (em "if") " compile-time linearity proves essential for correctness. "
|
||||
"The decision point is Step 5 (Linear Effects) of the foundations plan. "
|
||||
"If SX's own type system can enforce linearity at spec-validation time, "
|
||||
"OCaml's runtime enforcement is sufficient. If not, Koka becomes the better substrate."))
|
||||
|
||||
|
||||
;; -----------------------------------------------------------------------
|
||||
;; The path to self-hosting
|
||||
;; -----------------------------------------------------------------------
|
||||
|
||||
(~docs/section :title "The Path to Self-Hosting" :id "self-hosting"
|
||||
|
||||
(p "The end state: SX compiles itself. No intermediate language, no general-purpose host.")
|
||||
|
||||
(h4 :class "font-semibold mt-4 mb-2" "Phase 1: OCaml bootstrapper")
|
||||
(p "Write " (code "bootstrap_ml.py") " \u2014 reads " (code "cek.sx") " + " (code "frames.sx")
|
||||
" + " (code "primitives.sx") " + " (code "eval.sx") ", emits OCaml source. "
|
||||
"Same pattern as the existing Rust/Python/JS bootstrappers.")
|
||||
(p "The OCaml output is a standalone module:")
|
||||
(~docs/code :code (highlight "type value =\n | Nil | Bool of bool | Num of float | Str of string\n | Sym of string | Kw of string\n | List of value list | Dict of (value * value) list\n | Lambda of params * value list * env\n | Component of string * params * value list * env\n | Handle of int (* opaque FFI reference *)\n\ntype frame =\n | IfFrame of value list * value list * env\n | ArgFrame of value list * value list * env\n | MapFrame of value * value list * value list * env\n | ReactiveResetFrame of value\n | DerefFrame of value\n (* ... 20+ frame types from frames.sx *)\n\ntype kont = frame list\ntype state = value * env * kont\n\nlet step ((ctrl, env, kont) : state) : state =\n match ctrl with\n | Lit v -> continue_val v kont\n | Var name -> continue_val (Env.find name env) kont\n | App (f, args) -> (f, env, ArgFrame(args, [], env) :: kont)\n | ..." "ocaml"))
|
||||
|
||||
(h4 :class "font-semibold mt-6 mb-2" "Phase 2: Native + WASM builds")
|
||||
(p "Compile the OCaml output to:")
|
||||
(ul :class "list-disc list-inside space-y-1 mt-2"
|
||||
(li (code "sx_core.so") " / " (code "sx_core.dylib") " \u2014 native shared library, C ABI")
|
||||
(li (code "sx_core.wasm") " \u2014 via " (code "wasm_of_ocaml") " for browser")
|
||||
(li (code "sx_core.js") " \u2014 via " (code "js_of_ocaml") " as JS fallback"))
|
||||
(p "Python web framework calls " (code "sx_core.so") " via cffi. "
|
||||
"Browser loads " (code "sx_core.wasm") " via " (code "sx-platform.js") ".")
|
||||
|
||||
(h4 :class "font-semibold mt-6 mb-2" "Phase 3: SX evaluates web framework")
|
||||
(p "The compiled core evaluator loads web framework " (code ".sx") " at runtime "
|
||||
"(signals, engine, orchestration, boot). Same as the "
|
||||
(a :href "/sx/(etc.(plan.isolated-evaluator))" "Isolated Evaluator") " plan, "
|
||||
"but the evaluator is compiled OCaml/WASM instead of bootstrapped JS.")
|
||||
|
||||
(h4 :class "font-semibold mt-6 mb-2" "Phase 4: SX linearity checking")
|
||||
(p "Extend " (code "types.sx") " with quantity annotations:")
|
||||
(~docs/code :code (highlight ";; Quantity annotations on types\n(define-type (Signal a) :quantity :affine) ;; use at most once per scope\n(define-type (Channel a) :quantity :linear) ;; must be consumed exactly once\n\n;; Effect declarations with linearity\n(define-io-primitive \"send-message\"\n :params (channel message)\n :quantity :linear\n :effects [io]\n :doc \"Must be handled exactly once.\")\n\n;; The type checker (specced in .sx, compiled to OCaml) validates\n;; linearity at component registration time. Runtime enforcement\n;; by OCaml's one-shot continuations is the safety net." "lisp"))
|
||||
(p "The type checker runs at spec-validation time. The compiled evaluator "
|
||||
"executes already-verified code. SX's type system provides the linearity "
|
||||
"guarantees, not the host language.")
|
||||
|
||||
(h4 :class "font-semibold mt-6 mb-2" "Phase 5: Self-hosting compiler")
|
||||
(p "Write the compiler itself in SX:")
|
||||
(ul :class "list-disc list-inside space-y-1 mt-2"
|
||||
(li "Spec the CEK-to-native code generation in " (code ".sx") " files")
|
||||
(li "The Phase 2 OCaml evaluator compiles the compiler spec")
|
||||
(li "The compiled compiler can then compile itself")
|
||||
(li "OCaml becomes the bootstrap language only \u2014 "
|
||||
"needed once to get the self-hosting loop started, then never touched again"))
|
||||
|
||||
(~docs/code :code (highlight ";; The bootstrap chain\n\nStep 0: Python evaluator (existing)\n \u2193 evaluates bootstrap_ml.py\nStep 1: OCaml evaluator (compiled from spec by Python)\n \u2193 evaluates compiler.sx\nStep 2: SX compiler (compiled from .sx by OCaml evaluator)\n \u2193 compiles itself\nStep 3: SX compiler (compiled by itself)\n \u2193 compiles everything\n \u2193 emits native, WASM, JS from .sx spec\n \u2193 OCaml is no longer in the chain" "text"))
|
||||
|
||||
(p "At Step 3, the only language is SX. The compiler reads " (code ".sx") " and emits machine code. "
|
||||
"OCaml was the scaffolding. The scaffolding comes down."))
|
||||
|
||||
|
||||
;; -----------------------------------------------------------------------
|
||||
;; Concurrent CEK on OCaml 5
|
||||
;; -----------------------------------------------------------------------
|
||||
|
||||
(~docs/section :title "Concurrent CEK on OCaml 5" :id "concurrent-cek"
|
||||
|
||||
(p "OCaml 5's concurrency model maps directly onto the "
|
||||
(a :href "/sx/(etc.(plan.foundations))" "Foundations") " plan's concurrent CEK spec.")
|
||||
|
||||
(h4 :class "font-semibold mt-4 mb-2" "Mapping")
|
||||
(div :class "overflow-x-auto rounded border border-stone-200 mb-4"
|
||||
(table :class "w-full text-left text-sm"
|
||||
(thead (tr :class "border-b border-stone-200 bg-stone-100"
|
||||
(th :class "px-3 py-2 font-medium text-stone-600" "SX primitive")
|
||||
(th :class "px-3 py-2 font-medium text-stone-600" "OCaml 5")
|
||||
(th :class "px-3 py-2 font-medium text-stone-600" "Characteristic")))
|
||||
(tbody
|
||||
(tr :class "border-b border-stone-100"
|
||||
(td :class "px-3 py-2 text-stone-700" (code "spawn"))
|
||||
(td :class "px-3 py-2 text-stone-700" "Fiber via " (code "perform Spawn"))
|
||||
(td :class "px-3 py-2 text-stone-600" "Lightweight, scheduled by effect handler"))
|
||||
(tr :class "border-b border-stone-100"
|
||||
(td :class "px-3 py-2 text-stone-700" (code "channel"))
|
||||
(td :class "px-3 py-2 text-stone-700" (code "Eio.Stream"))
|
||||
(td :class "px-3 py-2 text-stone-600" "Typed, bounded, backpressure"))
|
||||
(tr :class "border-b border-stone-100"
|
||||
(td :class "px-3 py-2 text-stone-700" (code "yield!"))
|
||||
(td :class "px-3 py-2 text-stone-700" (code "perform Yield"))
|
||||
(td :class "px-3 py-2 text-stone-600" "Cooperative, zero-cost"))
|
||||
(tr :class "border-b border-stone-100"
|
||||
(td :class "px-3 py-2 text-stone-700" (code "select"))
|
||||
(td :class "px-3 py-2 text-stone-700" (code "Eio.Fiber.any"))
|
||||
(td :class "px-3 py-2 text-stone-600" "First-to-complete"))
|
||||
(tr :class "border-b border-stone-100"
|
||||
(td :class "px-3 py-2 text-stone-700" (code "fork-join"))
|
||||
(td :class "px-3 py-2 text-stone-700" (code "Eio.Fiber.all"))
|
||||
(td :class "px-3 py-2 text-stone-600" "Structured concurrency"))
|
||||
(tr
|
||||
(td :class "px-3 py-2 text-stone-700" "DAG scheduler")
|
||||
(td :class "px-3 py-2 text-stone-700" "Domains + fiber pool")
|
||||
(td :class "px-3 py-2 text-stone-600" "True parallelism across cores")))))
|
||||
|
||||
(p "Each concurrent CEK machine is a fiber. The scheduler is an effect handler. "
|
||||
"This isn't simulating concurrency \u2014 it's using native concurrency whose mechanism " (em "is") " effects.")
|
||||
|
||||
(h4 :class "font-semibold mt-4 mb-2" "The Art DAG connection")
|
||||
(p "Art DAG's 3-phase execution (analyze \u2192 plan \u2192 execute) maps onto "
|
||||
"concurrent CEK + OCaml domains:")
|
||||
(ul :class "list-disc list-inside space-y-1 mt-2"
|
||||
(li "Analyze: single CEK machine walks the DAG graph (one fiber)")
|
||||
(li "Plan: resolve dependencies, topological sort (pure computation)")
|
||||
(li "Execute: spawn one fiber per independent node, fan out to domains (true parallelism)")
|
||||
(li "GPU kernels: fiber performs " (code "Gpu_dispatch") " effect, handler calls into GPU via C FFI")))
|
||||
|
||||
|
||||
;; -----------------------------------------------------------------------
|
||||
;; Linear effects
|
||||
;; -----------------------------------------------------------------------
|
||||
|
||||
(~docs/section :title "Linear Effects" :id "linear-effects"
|
||||
|
||||
(p "The linearity axis from foundations. Two enforcement layers:")
|
||||
|
||||
(h4 :class "font-semibold mt-4 mb-2" "Layer 1: SX type system (primary)")
|
||||
(p "Quantity annotations in " (code "types.sx") " checked at spec-validation time:")
|
||||
(ul :class "list-disc list-inside space-y-1 mt-2"
|
||||
(li (code ":linear") " (1) \u2014 must be used exactly once")
|
||||
(li (code ":affine") " (\u22641) \u2014 may be used at most once (can drop)")
|
||||
(li (code ":unrestricted") " (\u03c9) \u2014 may be used any number of times"))
|
||||
(p "Linear effects guarantee: a " (code "send-message") " effect is handled exactly once. "
|
||||
"A channel is consumed. A resource handle is closed. "
|
||||
"The type checker proves this before the evaluator ever runs.")
|
||||
|
||||
(h4 :class "font-semibold mt-4 mb-2" "Layer 2: Host runtime (safety net)")
|
||||
(p "OCaml 5's one-shot continuations enforce linearity at runtime. "
|
||||
"A continuation can only be " (code "continue") "'d once \u2014 second invocation raises an exception. "
|
||||
"This catches any bugs in the type checker itself.")
|
||||
(p "If Koka replaces OCaml: compile-time enforcement replaces runtime enforcement. "
|
||||
"The safety net becomes a proof. Same semantics, stronger guarantees.")
|
||||
|
||||
(h4 :class "font-semibold mt-4 mb-2" "Decision point")
|
||||
(p "When Step 5 (Linear Effects) of the foundations plan is reached:")
|
||||
(ul :class "list-disc list-inside space-y-2 mt-2"
|
||||
(li "If SX's type checker can enforce linearity reliably \u2192 "
|
||||
(strong "stay on OCaml") ". Runtime one-shot is sufficient.")
|
||||
(li "If linearity bugs keep slipping through \u2192 "
|
||||
(strong "switch to Koka") ". Compile-time enforcement closes the gap.")
|
||||
(li "If the self-hosting compiler (Phase 5) reaches maturity \u2192 "
|
||||
(strong "it doesn't matter") ". SX compiles itself, the substrate is an implementation detail.")))
|
||||
|
||||
|
||||
;; -----------------------------------------------------------------------
|
||||
;; Compiled all the way down
|
||||
;; -----------------------------------------------------------------------
|
||||
|
||||
(~docs/section :title "Compiled All the Way Down" :id "compiled"
|
||||
|
||||
(p "The self-hosting compiler doesn't just compile the evaluator. "
|
||||
"It compiles " (em "everything") ". Component definitions, page layouts, "
|
||||
"event handlers, signal computations \u2014 all compiled to native machine code. "
|
||||
"SX is not an interpreted scripting language with a nice spec. "
|
||||
"It's a compiled language whose compiler also runs in the browser.")
|
||||
|
||||
(h4 :class "font-semibold mt-4 mb-2" "JIT in the browser")
|
||||
(p "The server sends SX (component definitions, page content). "
|
||||
"The client receives it and " (strong "compiles to WASM and executes") ". "
|
||||
"Not interprets. Not dispatches bytecodes. Compiles.")
|
||||
|
||||
(~docs/code :code (highlight "Server sends: (defcomp ~card (&key title) (div :class \"card\" (h2 title)))\n\nClient does:\n 1. Parse SX source (fast \u2014 it's s-expressions)\n 2. Hash AST \u2192 CID\n 3. Cache hit? Call the already-compiled WASM function\n 4. Cache miss? Compile to WASM, cache by CID, call it\n\nStep 4 is the JIT. The compiler (itself WASM) emits a WASM\nfunction, instantiates it via WebAssembly.instantiate, caches\nthe module by CID. Next time: direct function call, zero overhead." "text"))
|
||||
|
||||
(p "This is what V8 does with JavaScript. What LuaJIT does with Lua. "
|
||||
"The difference: SX's semantics are simpler (no prototype chains, no " (code "this")
|
||||
" binding, no implicit coercion), so the compiler is simpler. "
|
||||
"And content-addressing means compiled artifacts are cacheable by CID \u2014 "
|
||||
"compile once, store forever.")
|
||||
|
||||
(h4 :class "font-semibold mt-4 mb-2" "The compilation tiers")
|
||||
|
||||
(~docs/code :code (highlight "Tier 0: .sx source \u2192 tree-walking CEK (correct, slow \u2014 current)\nTier 1: .sx source \u2192 bytecodes \u2192 dispatch loop (correct, fast)\nTier 2: .sx source \u2192 WASM functions \u2192 execute (correct, fastest)\nTier 3: .sx source \u2192 native machine code (ahead-of-time, maximum)" "text"))
|
||||
|
||||
(p "Each tier is faster. Tier 1 (bytecodes) is the "
|
||||
(a :href "/sx/(etc.(plan.wasm-bytecode-vm))" "WASM Bytecode VM")
|
||||
" plan \u2014 compact wire format, no parse overhead, better cache locality. "
|
||||
"Tier 2 is JIT \u2014 the compiler emitting WASM functions on the fly. "
|
||||
"Tier 3 is AOT \u2014 the entire app precompiled. "
|
||||
"All tiers use the same spec, same platform layer, same platform primitives.")
|
||||
|
||||
(h4 :class "font-semibold mt-4 mb-2" "Server-side precompilation")
|
||||
(p "The server can compile too. Instead of sending SX source for the client to JIT, "
|
||||
"send precompiled WASM:")
|
||||
|
||||
(~docs/code :code (highlight ";; Option A: send SX source, client JIT compiles\nContent-Type: text/sx\n\n(div :class \"card\" (h2 \"hello\"))\n\n;; Option B: send precompiled WASM, client instantiates directly\nContent-Type: application/wasm\nX-Sx-Cid: bafyrei...\n\n<binary WASM module>" "text"))
|
||||
|
||||
(p "Option B skips parsing and compilation entirely. The client instantiates "
|
||||
"the WASM module and calls it. The server did all the work.")
|
||||
|
||||
(h4 :class "font-semibold mt-4 mb-2" "Content-addressed compilation cache")
|
||||
(p "Every " (code ".sx") " expression has a CID. Every compiled artifact has a CID. "
|
||||
"The mapping is deterministic \u2014 the compiler is a pure function:")
|
||||
|
||||
(~docs/code :code (highlight "source CID \u2192 compiled WASM CID\nbafyrei... \u2192 bafyrei...\n\nThis mapping is cacheable everywhere:\n\u2022 Browser cache \u2014 first visitor compiles, second visitor gets cached WASM\n\u2022 CDN \u2014 compiled artifacts served at the edge\n\u2022 IPFS \u2014 content-addressed by definition, globally deduplicated\n\u2022 Local disk \u2014 offline apps work from cached compiled components" "text"))
|
||||
|
||||
(h4 :class "font-semibold mt-4 mb-2" "Entire apps as machine code")
|
||||
(p "The entire application can be ahead-of-time compiled to a WASM binary. "
|
||||
"Component definitions, page layouts, event handlers, signal computations \u2014 "
|
||||
"all compiled to native WASM functions. The \"app\" is a " (code ".wasm") " file. "
|
||||
"The platform layer provides DOM and fetch. Everything in between is compiled machine code.")
|
||||
(p "The only thing that stays JIT-compiled is truly dynamic content \u2014 "
|
||||
"user-generated SX, REPL input, " (code "eval") "'d strings. "
|
||||
"And even those get JIT'd on first use and cached by CID.")
|
||||
|
||||
(h4 :class "font-semibold mt-4 mb-2" "The architecture")
|
||||
|
||||
(~docs/code :code (highlight "sx-platform.js \u2190 DOM, fetch, timers (the real world)\n \u2191 calls\nsx-compiler.wasm \u2190 the SX compiler (itself compiled to WASM)\n \u2191 compiles\n.sx source \u2190 received from server / cache / inline\n \u2193 emits\nnative WASM functions \u2190 cached by CID, instantiated on demand\n \u2193 executes\nactual DOM mutations via platform primitives" "text"))
|
||||
|
||||
(p "The compiler is WASM. The code it produces is WASM. "
|
||||
"It's compiled code all the way down. "
|
||||
"The only interpreter in the system is the CPU."))
|
||||
|
||||
|
||||
;; -----------------------------------------------------------------------
|
||||
;; How this changes existing plans
|
||||
;; -----------------------------------------------------------------------
|
||||
|
||||
(~docs/section :title "Impact on Existing Plans" :id "impact"
|
||||
|
||||
(div :class "overflow-x-auto rounded border border-stone-200 mb-4"
|
||||
(table :class "w-full text-left text-sm"
|
||||
(thead (tr :class "border-b border-stone-200 bg-stone-100"
|
||||
(th :class "px-3 py-2 font-medium text-stone-600" "Plan")
|
||||
(th :class "px-3 py-2 font-medium text-stone-600" "Impact")))
|
||||
(tbody
|
||||
(tr :class "border-b border-stone-100"
|
||||
(td :class "px-3 py-2 text-stone-700"
|
||||
(a :href "/sx/(etc.(plan.rust-wasm-host))" "Rust/WASM Host"))
|
||||
(td :class "px-3 py-2 text-stone-600"
|
||||
"Superseded. OCaml/WASM replaces Rust/WASM. The handle table and platform layer design carry over."))
|
||||
(tr :class "border-b border-stone-100"
|
||||
(td :class "px-3 py-2 text-stone-700"
|
||||
(a :href "/sx/(etc.(plan.isolated-evaluator))" "Isolated Evaluator"))
|
||||
(td :class "px-3 py-2 text-stone-600"
|
||||
"Architecture preserved. sx-platform.js and evaluator isolation apply to the OCaml evaluator too. The JS evaluator becomes a fallback."))
|
||||
(tr :class "border-b border-stone-100"
|
||||
(td :class "px-3 py-2 text-stone-700"
|
||||
(a :href "/sx/(etc.(plan.foundations))" "Foundations"))
|
||||
(td :class "px-3 py-2 text-stone-600"
|
||||
"Accelerated. OCaml 5 has native effects/continuations/fibers. Steps 4 (Concurrent CEK) and 5 (Linear Effects) map directly."))
|
||||
(tr :class "border-b border-stone-100"
|
||||
(td :class "px-3 py-2 text-stone-700"
|
||||
(a :href "/sx/(etc.(plan.wasm-bytecode-vm))" "WASM Bytecode VM"))
|
||||
(td :class "px-3 py-2 text-stone-600"
|
||||
"Complementary. OCaml gives tree-walking CEK. Bytecode VM is a future optimization on top."))
|
||||
(tr
|
||||
(td :class "px-3 py-2 text-stone-700"
|
||||
(a :href "/sx/(etc.(plan.self-hosting-bootstrapper))" "Self-Hosting Bootstrapper"))
|
||||
(td :class "px-3 py-2 text-stone-600"
|
||||
"Converges. js.sx and py.sx are self-hosting emitters. The self-hosting SX compiler (Phase 5 here) is the logical endpoint."))))))
|
||||
|
||||
|
||||
;; -----------------------------------------------------------------------
|
||||
;; Principles
|
||||
;; -----------------------------------------------------------------------
|
||||
|
||||
(~docs/section :title "Principles" :id "principles"
|
||||
(ul :class "list-disc list-inside space-y-2"
|
||||
(li (strong "SX is the language.") " Not OCaml, not Rust, not Haskell. "
|
||||
"Those are substrates. SX defines the semantics, SX checks the types, "
|
||||
"SX will ultimately compile itself.")
|
||||
(li (strong "OCaml is scaffolding.") " The closest existing language to CEK. "
|
||||
"Used to bootstrap the self-hosting compiler. Comes down when the compiler is mature.")
|
||||
(li (strong "The spec is the compiler's input.") " " (code "cek.sx") ", " (code "frames.sx")
|
||||
", " (code "primitives.sx") " \u2014 the same files that define the language "
|
||||
"become the compiler's source. One truth, one artifact.")
|
||||
(li (strong "Platforms provide effects, not evaluation.") " Python provides database/HTTP. "
|
||||
"JavaScript provides DOM. GPU provides tensor ops. "
|
||||
"The evaluator is always compiled SX, embedded via FFI or WASM.")
|
||||
(li (strong "Linearity belongs in the spec.") " SX's type system checks it. "
|
||||
"The host provides runtime backup. If the type system is sound, the runtime check never fires.")
|
||||
(li (strong "One language, every target.") " Not \"one spec, multiple implementations.\" "
|
||||
"One " (em "compiled") " evaluator, deployed as native/.wasm/.js depending on context. "
|
||||
"The evaluator binary is the same code everywhere. Only the platform layer changes.")))
|
||||
|
||||
|
||||
;; -----------------------------------------------------------------------
|
||||
;; Outcome
|
||||
;; -----------------------------------------------------------------------
|
||||
|
||||
(~docs/section :title "Outcome" :id "outcome"
|
||||
(p "After completion:")
|
||||
(ul :class "list-disc list-inside space-y-2 mt-2"
|
||||
(li "SX core evaluator compiled from spec via OCaml \u2014 native + WASM from one codebase.")
|
||||
(li "Python web framework calls native " (code "sx_core.so") " for rendering \u2014 "
|
||||
"100\u20131000x faster than interpreted Python.")
|
||||
(li "Browser loads " (code "sx_core.wasm") " \u2014 same evaluator, same spec, near-native speed.")
|
||||
(li "Concurrent CEK runs on OCaml 5 fibers/domains \u2014 true parallelism for Art DAG.")
|
||||
(li "Linear effects validated by SX type system, enforced by OCaml one-shot continuations.")
|
||||
(li "Self-hosting compiler: SX compiles itself to machine code. OCaml scaffolding removed.")
|
||||
(li "The architecture proof: one language, one compiled evaluator, "
|
||||
"every platform just provides effects."))
|
||||
|
||||
(p :class "text-stone-500 text-sm italic mt-12"
|
||||
"The Mother Language was always SX. We just needed to find the right scaffolding to stand it up."))))
|
||||
@@ -581,6 +581,8 @@
|
||||
"cek-reactive" (~plans/cek-reactive/plan-cek-reactive-content)
|
||||
"reactive-runtime" (~plans/reactive-runtime/plan-reactive-runtime-content)
|
||||
"rust-wasm-host" (~plans/rust-wasm-host/plan-rust-wasm-host-content)
|
||||
"isolated-evaluator" (~plans/isolated-evaluator/plan-isolated-evaluator-content)
|
||||
"mother-language" (~plans/mother-language/plan-mother-language-content)
|
||||
:else (~plans/index/plans-index-content))))
|
||||
|
||||
;; ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user