# 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/**` and `plans/elm-on-sx.md`. Do **not** edit `spec/`,
  `hosts/`, `shared/`, or other `lib/<lang>/`.
- **Shared-file issues** go under "Blockers" below with a minimal repro; do not fix here.
- **SX files:** use `sx-tree` MCP 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 log` updated 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` → SX `perform` IO request
- `Sub` → SX event listener registered via `dom-listen`
- `Maybe a` → `nil` (Nothing) or value (Just a) — uses ADTs from Phase 6 of primitives
- `Result 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-ast` entry
- [ ] Arithmetic, string `++`, comparison, boolean ops
- [ ] Lambda → SX `fn`; function application
- [ ] `let`/`in` → SX `let`
- [ ] `if`/`then`/`else` → SX `if`
- [ ] `case`/`of` with constructor, literal, tuple, list, wildcard patterns → SX `cond`
      using ADT match (Phase 6 primitives)
- [ ] List ops: `List.map`, `List.filter`, `List.foldl`, `List.foldr`
- [ ] `Maybe` and `Result` as 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 events
- [ ] `Html.*` shims: `div`, `p`, `button`, `input`, `text`, `h1`–`h6`, `ul`, `li`, `a`,
      `span`, `img` — emit SX component calls
- [ ] `Html.Attributes.*`: `class`, `id`, `href`, `src`, `type_`, `placeholder`, `value`
- [ ] `Html.Events.*`: `onClick`, `onInput`, `onSubmit`, `onBlur`, `onFocus`
- [ ] `Browser.element` — adds `init` returning `(model, Cmd msg)`, `subscriptions`
- [ ] Demo: counter app (`init=0`, `update Increment m = m+1`, `view` shows count + button)

### Phase 4 — Cmds and Subs
- [ ] `Cmd` — mapped to SX `perform` IO requests. `Cmd.none`, `Cmd.batch`
- [ ] `Http.get`/`Http.post` → SX fetch IO
- [ ] `Sub` — mapped to SX `dom-listen`. `Sub.none`, `Sub.batch`
- [ ] `Browser.Events.onClick`, `onKeyPress`, `onAnimationFrame`
- [ ] `Time.every` — periodic subscription via SX timer IO
- [ ] `Task.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`, `fromFloat`
- [ ] `List.*` — `map`, `filter`, `foldl`, `foldr`, `head`, `tail`, `isEmpty`, `length`,
      `reverse`, `append`, `concat`, `member`, `sort`, `sortBy`, `indexedMap`, `range`
- [ ] `Dict.*` — SX immutable dict; `fromList`, `toList`, `get`, `insert`, `remove`, `update`,
      `member`, `keys`, `values`, `map`, `filter`, `foldl`
- [ ] `Set.*` — SX set primitive (Phase 18); `fromList`, `toList`, `member`, `insert`,
      `remove`, `union`, `intersect`, `diff`
- [ ] `Maybe.*` — `withDefault`, `map`, `andThen`, `map2`
- [ ] `Result.*` — `withDefault`, `map`, `andThen`, `mapError`, `toMaybe`
- [ ] `Tuple.*` — `first`, `second`, `pair`, `mapFirst`, `mapSecond`
- [ ] `Basics.*` — `identity`, `always`, `not`, `xor`, `modBy`, `remainderBy`, `clamp`,
      `min`, `max`, `abs`, `sqrt`, `logBase`, `e`, `pi`, `floor`, `ceiling`, `round`,
      `truncate`, `toFloat`, `isNaN`, `isInfinite`, `compare`
- [ ] `Random.*` — seed-based PRNG via SX IO perform

### Phase 6 — full browser integration
- [ ] `Browser.application` — URL routing, `onUrlChange`, `onUrlRequest`
- [ ] `Browser.Navigation.*` — `pushUrl`, `replaceUrl`, `back`, `forward`
- [ ] `Url.Parser.*` — path segment parsing
- [ ] `Json.Decode.*` — JSON decoder combinators
- [ ] `Json.Encode.*` — JSON encoder
- [ ] `Ports` — `port` keyword; JS interop via SX `host-call`

## Blockers

_(none yet)_

## Progress log

_Newest first._

_(awaiting phase 1)_
