Hyperscript compiler/runtime:
- query target support in set/fire/put commands
- hs-set-prolog-hook! / hs-prolog-hook / hs-prolog in runtime
- runtime log-capture cleanup
Scripts: sx-loops-up/down, sx-hs-e-up/down, sx-primitives-down
Plans: datalog, elixir, elm, go, koka, minikanren, ocaml, hs-bucket-f,
designs (breakpoint, null-safety, step-limit, tell, cookies, eval,
plugin-system)
lib/prolog/hs-bridge.sx: initial hook-based bridge draft
lib/common-lisp/tests/runtime.sx: CL runtime tests
WASM: regenerate sx_browser.bc.js from updated hs sources
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
6.3 KiB
6.3 KiB
Elm-on-SX: Elm 0.19 on the CEK/VM
Compile Elm source to SX AST; the existing CEK evaluator runs it. The unique angle: SX's
reactive island system (defisland, signals, provide/context) is a natural host for
The Elm Architecture — Model/Update/View maps almost directly onto SX's reactive runtime.
This is the only language in the set that targets SX's browser-side reactivity rather than
the server-side evaluator.
End-state goal: core Elm programs running in the browser via SX islands, with The Elm Architecture wired to SX signals. Not a full Elm compiler — no exhaustiveness checking, no module system, no type inference — but a faithful runtime that can run Elm programs written in idiomatic style.
Ground rules
- Scope: only touch
lib/elm/**andplans/elm-on-sx.md. Do not editspec/,hosts/,shared/, or otherlib/<lang>/. - Shared-file issues go under "Blockers" below with a minimal repro; do not fix here.
- SX files: use
sx-treeMCP tools only. - Architecture: Elm source → Elm AST → SX AST. No standalone Elm evaluator.
- Type system: defer. Focus on runtime semantics. Type errors surface at eval time.
- Commits: one feature per commit. Keep
## Progress logupdated and tick boxes.
Architecture sketch
Elm source text
│
▼
lib/elm/tokenizer.sx — numbers, strings, idents, operators, indentation-sensitive lexer
│
▼
lib/elm/parser.sx — Elm AST: module, import, type alias, type, let, case, lambda,
│ if, list/tuple/record literals, pipe operator |>
▼
lib/elm/transpile.sx — Elm AST → SX AST
│
▼
lib/elm/runtime.sx — TEA runtime: Program, sandbox, element; Cmd/Sub wrappers;
│ Html.* shims; Browser.* shims
▼
SX island / reactive runtime (browser)
Key semantic mappings:
Model→ SX signal (make-signal)update : Msg -> Model -> Model→ SX signal updater (called on each message)view : Model -> Html Msg→ SX component (re-renders on model signal change)Cmd→ SXperformIO requestSub→ SX event listener registered viadom-listenMaybe a→nil(Nothing) or value (Just a) — uses ADTs from Phase 6 of primitivesResult a b→ ADT(Ok val)/(Err err)
Roadmap
Phase 1 — tokenizer + parser
- Tokenizer: keywords (
module,import,type,alias,let,in,if,then,else,case,of,port), indentation tokens (indent/dedent/newline), string literals, number literals, operators (|>,>>,<<,<|,++,::), type vars - Parser: module declaration, imports, type aliases, union types, function definitions
with pattern matching,
let/in,case/of,if/then/else, lambda\x -> e, list literals[1,2,3], tuple literals(a,b), record literals{x=1, y=2}, record update{ r | x = 1 }, pipe operator|> - Skip for phase 1: ports, subscriptions, effects manager, type annotations
- Tests in
lib/elm/tests/parse.sx
Phase 2 — transpile: expressions + pattern matching
elm-eval-astentry- Arithmetic, string
++, comparison, boolean ops - Lambda → SX
fn; function application let/in→ SXletif/then/else→ SXifcase/ofwith constructor, literal, tuple, list, wildcard patterns → SXcondusing ADT match (Phase 6 primitives)- List ops:
List.map,List.filter,List.foldl,List.foldr MaybeandResultas ADTs- 30+ eval tests in
lib/elm/tests/eval.sx
Phase 3 — The Elm Architecture runtime
Browser.sandbox— pure TEA loop (no Cmds, no Subs){ init : model, update : msg -> model -> model, view : model -> Html msg }Wires to: SX signal for model, SX component for view, message dispatch on user eventsHtml.*shims:div,p,button,input,text,h1–h6,ul,li,a,span,img— emit SX component callsHtml.Attributes.*:class,id,href,src,type_,placeholder,valueHtml.Events.*:onClick,onInput,onSubmit,onBlur,onFocusBrowser.element— addsinitreturning(model, Cmd msg),subscriptions- Demo: counter app (
init=0,update Increment m = m+1,viewshows count + button)
Phase 4 — Cmds and Subs
Cmd— mapped to SXperformIO requests.Cmd.none,Cmd.batchHttp.get/Http.post→ SX fetch IOSub— mapped to SXdom-listen.Sub.none,Sub.batchBrowser.Events.onClick,onKeyPress,onAnimationFrameTime.every— periodic subscription via SX timer IOTask.perform/Task.attempt— single-shot async operations
Phase 5 — standard library
String.*—length,append,concat,split,join,trim,toUpper,toLower,contains,startsWith,endsWith,replace,toInt,toFloat,fromInt,fromFloatList.*—map,filter,foldl,foldr,head,tail,isEmpty,length,reverse,append,concat,member,sort,sortBy,indexedMap,rangeDict.*— SX immutable dict;fromList,toList,get,insert,remove,update,member,keys,values,map,filter,foldlSet.*— SX set primitive (Phase 18);fromList,toList,member,insert,remove,union,intersect,diffMaybe.*—withDefault,map,andThen,map2Result.*—withDefault,map,andThen,mapError,toMaybeTuple.*—first,second,pair,mapFirst,mapSecondBasics.*—identity,always,not,xor,modBy,remainderBy,clamp,min,max,abs,sqrt,logBase,e,pi,floor,ceiling,round,truncate,toFloat,isNaN,isInfinite,compareRandom.*— seed-based PRNG via SX IO perform
Phase 6 — full browser integration
Browser.application— URL routing,onUrlChange,onUrlRequestBrowser.Navigation.*—pushUrl,replaceUrl,back,forwardUrl.Parser.*— path segment parsingJson.Decode.*— JSON decoder combinatorsJson.Encode.*— JSON encoderPorts—portkeyword; JS interop via SXhost-call
Blockers
(none yet)
Progress log
Newest first.
(awaiting phase 1)