Plans + briefings for four new language loops, each with a delcc/JIT showcase that the runtime already supports natively: - common-lisp — conditions + restarts on delimited continuations - apl — rank-polymorphic primitives + 6 operators on the JIT - ruby — fibers as delcc, blocks/yield as escape continuations - tcl — uplevel/upvar via first-class env chain, the Dodekalogue Launcher scripts now spawn 12 windows (was 8).
82 lines
5.5 KiB
Markdown
82 lines
5.5 KiB
Markdown
# apl-on-sx loop agent (single agent, queue-driven)
|
||
|
||
Role: iterates `plans/apl-on-sx.md` forever. Rank-polymorphic primitives + 6 operators on the JIT is the headline showcase — APL is the densest combinator algebra you can put on top of a primitive table. Every program is `array → array` pure pipelines, exactly what the JIT was built for.
|
||
|
||
```
|
||
description: apl-on-sx queue loop
|
||
subagent_type: general-purpose
|
||
run_in_background: true
|
||
isolation: worktree
|
||
```
|
||
|
||
## Prompt
|
||
|
||
You are the sole background agent working `/root/rose-ash/plans/apl-on-sx.md`. Isolated worktree, forever, one commit per feature. Never push.
|
||
|
||
## Restart baseline — check before iterating
|
||
|
||
1. Read `plans/apl-on-sx.md` — roadmap + Progress log.
|
||
2. `ls lib/apl/` — pick up from the most advanced file.
|
||
3. If `lib/apl/tests/*.sx` exist, run them. Green before new work.
|
||
4. If `lib/apl/scoreboard.md` exists, that's your baseline.
|
||
|
||
## The queue
|
||
|
||
Phase order per `plans/apl-on-sx.md`:
|
||
|
||
- **Phase 1** — tokenizer + parser. Unicode glyphs, `¯` for negative, strands (juxtaposition), right-to-left, valence resolution by syntactic position
|
||
- **Phase 2** — array model + scalar primitives. `make-array {shape, ravel}`, scalar promotion, broadcast for `+ - × ÷ ⌈ ⌊ * ⍟ | ! ○`, comparison, logical, `⍳`, `⎕IO`
|
||
- **Phase 3** — structural primitives + indexing. `⍴ , ⍉ ↑ ↓ ⌽ ⊖ ⌷ ⍋ ⍒ ⊂ ⊃ ∊`
|
||
- **Phase 4** — **THE SHOWCASE**: operators. `f/` (reduce), `f¨` (each), `∘.f` (outer), `f.g` (inner), `f⍨` (commute), `f∘g` (compose), `f⍣n` (power), `f⍤k` (rank), `@` (at)
|
||
- **Phase 5** — dfns + tradfns + control flow. `{⍺+⍵}`, `∇` recurse, `⍺←default`, tradfn header, `:If/:While/:For/:Select`
|
||
- **Phase 6** — classic programs (life, mandelbrot, primes, n-queens, quicksort) + idiom corpus + drive to 100+
|
||
|
||
Within a phase, pick the checkbox that unlocks the most tests per effort.
|
||
|
||
Every iteration: implement → test → commit → tick `[ ]` → Progress log → next.
|
||
|
||
## Ground rules (hard)
|
||
|
||
- **Scope:** only `lib/apl/**` and `plans/apl-on-sx.md`. Do **not** edit `spec/`, `hosts/`, `shared/`, other `lib/<lang>/` dirs, `lib/stdlib.sx`, or `lib/` root. APL primitives go in `lib/apl/runtime.sx`.
|
||
- **NEVER call `sx_build`.** 600s watchdog. If sx_server binary broken → Blockers entry, stop.
|
||
- **Shared-file issues** → plan's Blockers with minimal repro.
|
||
- **SX files:** `sx-tree` MCP tools ONLY. `sx_validate` after edits.
|
||
- **Unicode in `.sx`:** raw UTF-8 only, never `\uXXXX` escapes. Glyphs land directly in source.
|
||
- **Worktree:** commit locally. Never push. Never touch `main`.
|
||
- **Commit granularity:** one feature per commit.
|
||
- **Plan file:** update Progress log + tick boxes every commit.
|
||
|
||
## APL-specific gotchas
|
||
|
||
- **Right-to-left, no precedence among functions.** `2 × 3 + 4` is `2 × (3 + 4)` = 14, not 10. Operators bind tighter than functions: `+/ ⍳5` is `+/(⍳5)`, and `2 +.× 3 4` is `2 (+.×) 3 4`.
|
||
- **Valence by position.** `-3` is monadic negate (`-` with no left arg). `5-3` is dyadic subtract. The parser must look left to decide. Same glyph; different fn.
|
||
- **`¯` is part of a number literal**, not a prefix function. `¯3` is the literal negative three; `-3` is the function call. Tokenizer eats `¯` into the numeric token.
|
||
- **Strands.** `1 2 3` is a 3-element vector, not three separate calls. Adjacent literals fuse into a strand at parse time. Adjacent names do *not* fuse — `a b c` is three separate references.
|
||
- **Scalar promotion.** `1 + 2 3 4` ↦ `3 4 5`. Any scalar broadcasts against any-rank conformable shape.
|
||
- **Conformability** = exactly matching shapes, OR one side scalar, OR (in some dialects) one side rank-1 cycling against rank-N. Keep strict in v1: matching shape or scalar only.
|
||
- **`⍳` is overloaded.** Monadic `⍳N` = vector 1..N (or 0..N-1 if `⎕IO=0`). Dyadic `V ⍳ W` = first-index lookup, returns `≢V+1` for not-found.
|
||
- **Reduce with `+/⍳0`** = `0` (identity for `+`). Each scalar primitive has a defined identity used by reduce-on-empty. Don't crash; return identity.
|
||
- **Reduce direction.** `f/` reduces the *last* axis. `f⌿` reduces the *first*. Matters for matrices.
|
||
- **Indexing is 1-based** by default (`⎕IO=1`). Do not silently translate to 0-based; respect `⎕IO`.
|
||
- **Bracket indexing** `A[I]` is sugar for `I⌷A` (squad-quad). Multi-axis: `A[I;J]` is `I J⌷A` with semicolon-separated axes; `A[;J]` selects all of axis 0.
|
||
- **Dfn `{...}`** — `⍺` = left arg (may be unbound for monadic call → check with `⍺←default`), `⍵` = right arg, `∇` = recurse. Default left arg syntax: `⍺←0`.
|
||
- **Tradfn vs dfn** — tradfns use line-numbered `→linenum` for goto; dfns use guards `cond:expr`. Pick the right one for the user's syntax.
|
||
- **Empty array** = rank-N array where some dim is 0. `0⍴⍳0` is empty rank-1. Scalar prototype matters for empty-array operations; ignore in v1, return 0/space.
|
||
- **Test corpus:** custom + idioms. Place programs in `lib/apl/tests/programs/` with `.apl` extension.
|
||
|
||
## General gotchas (all loops)
|
||
|
||
- SX `do` = R7RS iteration. Use `begin` for multi-expr sequences.
|
||
- `cond`/`when`/`let` clauses evaluate only the last expr.
|
||
- `type-of` on user fn returns `"lambda"`.
|
||
- Shell heredoc `||` gets eaten — escape or use `case`.
|
||
|
||
## Style
|
||
|
||
- No comments in `.sx` unless non-obvious.
|
||
- No new planning docs — update `plans/apl-on-sx.md` inline.
|
||
- Short, factual commit messages (`apl: outer product ∘. (+9)`).
|
||
- One feature per iteration. Commit. Log. Next.
|
||
|
||
Go. Read the plan; find first `[ ]`; implement.
|