Commit graph

9 commits

Author SHA1 Message Date
f7352b51b0 rename: uncommonlisp -> lumbda throughout the repo
Historical internal name "uncommonlisp" retired in favor of the
public name "lumbda" ahead of lumbda.com going live. Scope of
this commit:

Source files renamed:
  uncommonlisp.py                     -> lumbda.py
  asm/uncommonlisp.s                  -> asm/lumbda.s
  c/uncommonlisp.h                    -> c/lumbda.h
  whitepaper/uncommonlisp-whitepaper  -> whitepaper/lumbda-whitepaper (.rst + .pdf)

Binaries renamed (tracked ones; c/ was always gitignored):
  asm/uncommonlisp, asm/uncommonlisp-gc, asm/uncommonlisp.o,
  asm/uncommonlisp-gc.o                -> asm/lumbda(-gc)(.o)
  c/.gitignore                          -> ignores lumbda

Internal string updates (sed pass ordered longest-first):
  asm/uncommonlisp -> asm/lumbda
  c/uncommonlisp   -> c/lumbda
  uncommonlisp.py  -> lumbda.py
  UNCOMMONLISP_BIN -> LUMBDA_BIN (asm/test.sh env var)
  "uncommonlisp> " -> "lumbda> " (asm REPL prompt baked into binary)
  UNCOMMONLISP     -> LUMBDA (macros, comments)
  uncommonlisp     -> lumbda (prose)

Binary portal magic updated:
  "ULPORTAL" -> "LUMBDAB1"   # "Lumbda Binary v1"
Old portal files are not backward-compatible — this is a deliberate
break since it's the rename moment. S-expression portals already
carry their own ";; lumbda-portal v1" header and remain cleanly
versioned.

WHITEPAPER.pdf / WHITEPAPER.rst symlinks repointed to the renamed
files. Makefile's whitepaper target targets lumbda-whitepaper.pdf.

Not changed (intentional, separate phases):
  - Filesystem directory /home/fox/git/uncommonlisp itself
    (fox renames locally and the gitlab repo URL in a follow-up)
  - tests.py hardcoded cwd=/home/fox/git/uncommonlisp
    (matches the current on-disk location; will flip when the
    directory rename ships)
  - Git history (immutable; old commits still say uncommonlisp,
    which is correct — that's what they were)

Verified:
  137 asm no-GC + 137 asm GC + 571 Python + 83 C + 189 shared
  functional tests all pass under the new names.
  bench-gc-http (2000 req): all 4 cells behave as expected
  (cells 1/2 flat, 3 leaks, 4 bounded at 1 chunk).
  Python REPL, C REPL, asm REPL all start cleanly.
2026-04-19 10:20:11 -04:00
a606b6087e asm-gc: movb-not-orq type patch (kills residual "unbound variable")
Root-cause fix for the residual crashes I had documented as known
issues in §6.6.4. Every heap_alloc call site was setting its type
byte with `orq $(HT_X << 8), -8(%rax)` — but OR merges with the
stale type byte from a free-list-reused block. A pair previously
used as a vector (type 5 = 0b101) re-allocated as pair (type 1 =
0b001) ends up with merged type 0b101 = still vector. Walker then
treats the pair as a vector, reads the pair's car as a "length",
and walks off the block end — hence the hash-set bench's "unbound
variable: t", memory bench's "unbound variable: lst", arena bench's
"unbound variable: k".

Fix: overwrite the byte instead of OR-ing. 18 sites converted from
`orq $(HT_X << 8), -8(%rax)` to `movb $HT_X, -7(%rax)`. Every
previously-residual crash gone on first rerun.

Refreshed benchmark numbers throughout §6.6:

§6.6 Memory table: 122× less memory at 26% slowdown (was 124×,
30%). Range shifted because the fix also accelerated the common
paths; ratio stable.

§6.6.4 HTTP soak at 50,000 requests × 16 concurrent × 4 cells:
  no-GC + snapshot       630 req/s   peak 100 KB     growth 4 KB
  GC    + snapshot       633 req/s   peak 120 KB     growth 4 KB
  no-GC + no snapshot    625 req/s   peak 458 MB     OOM at cap
  GC    + no snapshot    610 req/s   peak 1,092 KB   growth 852 KB

Cell 4 now sustains 50K requests with steady-state 1-chunk memory.
Previous residual edge at 50K (cell 4 failing to start) was a
manifestation of the same type-byte bug, now gone.

§6.6.3 Adaptive numbers collapsed to within ~1% across all three
workloads (was 6% / 7% / 17% deltas). Paper updated to honestly
report adaptive as a null experiment on these shapes — neutral
cost, same stats surface, default on.

§6.6 diagram: bench-gc.png refreshed to match new numbers.

137 asm no-GC + 137 asm GC + 189 shared functional all pass.
Hash-set / memory / arena / adaptive / HTTP benches all clean.
2026-04-18 20:28:31 -04:00
3f1b1bc0ab whitepaper §6.6.3: collaborative adaptive meta-GC results
Adds §6.6.3 "Collaborative Meta-GC: From Greedy to Adaptive" with
the three-workload benchmark (friendly / hostile / mixed × greedy
/ adaptive). Honest read of the numbers:

  friendly  greedy    732 ms  1000 resets, 0 escapes
  friendly  adaptive  691 ms  1000 resets, 0 escapes       (-6%)
  hostile   greedy    568 ms     0 resets, 1000 escapes
  hostile   adaptive  607 ms     0 resets, 1000 escapes, 11 skipped (+7%)
  mixed     greedy   1981 ms    17 resets, 1983 escapes
  mixed     adaptive 1694 ms    14 resets, 1986 escapes, 2 skipped  (-17%)

Adaptive wins on friendly (-6%) and mixed (-17%, the policy's
design target). On fully hostile workloads implicit GC fires 982
of 1000 arenas before the dispatcher sees them, so the signal is
drowned and greedy happens to edge adaptive by ~7%. Section
explicitly calls out the collaborative-but-local structure
(shared state on arena_active + EMA + countdown, decisions made
locally by each component) and credits the benchmark work with
surfacing two real correctness bugs in the conservative stack
scan — 24-byte strings misread as env nodes, 40-byte strings
misread as 25-element vectors — both now fixed.

Also:
  - meta-gc-policy.dot rewritten to show the adaptive gate
    (rate > 50% + probe countdown) before the greedy verify path;
    new skip branch, new EMA annotations on edges.
  - §6 reproducibility list + Makefile bench-gc-adaptive target.
  - PDF rebuilt at 2.64 MB.

137 asm no-GC + 137 asm GC + 189 shared functional tests pass
against the new asm.
2026-04-18 11:35:27 -04:00
9b1a60226d whitepaper: diagrams + stats refresh for GC / meta-GC / hash primitives
Diagrams:
  - asm-architecture.dot: adds GC_NAIVE memory cluster (bump, free
    list, conservative stack scan) + meta-GC (with-arena) cluster
    showing the reset path; updates line count (4968 -> 6645),
    builtin count (91 -> 95+), mentions native hash-table-* /
    hash-set-* and the GC-build primitives (with-arena, gc-collect,
    gc-stats, arena-stats).
  - benchmark-binary-size.dot: adds second asm bar for the GC_NAIVE
    build (27 KB stripped vs 23 KB bump-only); updated asm bump
    size from 22 KB (stale) to actual 23 KB.
  - benchmark-gc.dot (new): side-by-side peak RSS for asm bump-only
    (134 MB), naive GC (1.1 MB), meta-GC arena (1.2 MB, 2000/2000
    resets); embedded in §6.6.
  - meta-gc-policy.dot (new): three-way decision tree at
    (with-arena) exit — implicit-GC-fired / mark-in-arena-range /
    no-mark-in-range -> skip / sweep / bulk-reset; embedded in
    §6.6.1.

Stats:
  - 975 verified assertions -> 980 (asm gained 5 via hash-table &
    hash-set tests; 571 Python + 137 asm + 83 C + 189 shared).
  - asm test count 132 -> 137 in the summary list, intro abstract,
    and §11 tier table. Notes that the optional GC build passes
    the same 137 independently (1,117 assertions total when both
    asm binaries are exercised).
  - Stale 4,968 LOC -> 6,645 already fixed in the prior commit;
    the new asm-architecture diagram now matches.

PDF rebuilt, 2.58 MB (was 2.40 MB). All test suites green.
2026-04-18 10:46:29 -04:00
aff292ebc8 whitepaper: actually use diagrams — 5 PNGs embedded, .dot sources refreshed
Fox flagged that the "A diagram is worth 10,000 words" quote
appeared twice in the paper but nothing was actually illustrated.
Fixed by:

1. Refreshing every .dot source to match current reality:
   - docs/asm-architecture.dot: 22 KB (was "13 KB"), 14 syscalls
     (was 4), 91 builtins (was 34), djb2 hash (was "linear scan"),
     TCP stack + heap-snapshot + portal boxes added.
   - docs/benchmark-sumto.dot: sum-to(1M) i5-8350U numbers; C
     --fast 238 ms, asm 670 ms, Python --fast 5,136 ms. Was
     sum-to(50k) with stale numbers.
   - docs/benchmark-ack.dot: ackermann(3,8) i5-8350U numbers. Was
     ack(3,4) with stale numbers.
   - docs/benchmark-binary-size.dot: asm 22 KB, C 205 KB, busybox
     2.1 MB, python3 8.0 MB. Was comparing against different
     baselines.

2. Regenerated all PNGs via `make docs`.

3. Embedded in the paper at meaningful points:
   - §2 Architecture (Python): python-architecture.png
   - §6.4 Three-way bench: benchmark-sumto.png, benchmark-ack.png
   - §11 Three Implementations: c-architecture.png, asm-
     architecture.png
   - §11.3 HTTP + sockets: benchmark-binary-size.png

4. Removed the redundant quote from §12.3; the one in §11
   remains because §11 now follows it with two real diagrams.

Prerequisite fox noted: "make sure diagrams are up to date before
using them to code." Done — every embedded figure has the current
numbers/topology, not the old ones.
2026-04-17 19:09:16 -04:00
5fb1f0cb17 Add benchmark dot diagrams showing performance differences
5 new diagrams (Graphviz DOT → PNG):
  benchmark-ack.dot      — ack(3,4) across all 5 tiers
  benchmark-sumto.dot    — sum-to(50k) across all 5 tiers
  benchmark-fib.dot      — fib(35) iterative across all 5 tiers
  benchmark-speedup.dot  — JIT speedup ratios (7x-784x)
  benchmark-binary-size.dot — 13KB asm vs 171KB C vs ~30MB Python

JIT: 0.19ms ack, 7x faster than CPython, 784x faster than Python VM.
Makefile docs target now auto-discovers all docs/*.dot files.
2026-04-16 13:01:32 -04:00
d49c01d0bf Update docs and whitepaper with concrete benchmarks
Fresh in-process benchmarks across all implementations:
  JIT:        ack 0.19ms, fib 0.09ms, sum 0.55ms
  CPython:    ack 1.3ms,  fib 0.006ms, sum 5.5ms
  C interp:   ack 20ms,   fib 0.06ms,  sum 109ms
  Python VM:  ack 149ms,  fib 0.75ms,  sum 437ms
  Assembly:   ack 8ms,    fib 0.6ms,   sum 43ms

JIT runs Scheme 7-10x faster than CPython runs Python.

Updated: language identified as R7RS Scheme throughout.
Test count updated to 943 across all implementations.
2026-04-16 12:52:55 -04:00
670487c01d Add architecture docs with dot diagrams, update Makefile and CLAUDE.md
4 architecture diagrams (Graphviz DOT → PNG):
  python-architecture.dot  — bytecode VM + continuations + portal
  c-architecture.dot       — tree-walker + VM + JIT tiers
  asm-architecture.dot     — syscalls-only, 13KB binary
  jit-pipeline.dot         — AST → x86_64 machine code flow

docs/README.md — full architecture docs with embedded diagrams
and performance summary across all implementations.

Makefile: add asm-repl, docs target, clean-docs. Header comments
document all targets and test suites.

CLAUDE.md: add "A diagram is worth 10,000 words" (russell@unturf.com),
implementation table, test suite inventory.

Assembly is 2.5-4x faster than C interpreter on recursive workloads.
JIT remains 33x faster than hand-written assembly.
2026-04-15 14:07:59 -04:00
46812e1885 Add GPU architecture notes and JIT header
docs/gpu-architecture.md — roadmap for GPU lambda execution:
  Phase 1: map/reduce (CUDA thread per element)
  Phase 2: trampolining (recursive lambdas without stack)
  Phase 3: interaction combinators (Bend/HVM approach, 74K MIPS)

c/jit.h — x86_64 JIT header: JitBlock, JitFunc typedef,
  jit_compile/jit_free API. Uses mmap for executable memory.
  System V AMD64 ABI calling convention.

jit.c implementation in progress (x86 instruction encoding).
2026-04-14 19:43:16 -04:00