Zoë Trout's favorites at wedgewack.org/ursa.lisp.txt are Common Lisp:
iterative LOOP macros, setf cascades, defun with &optional, image-
based stone-lisp culture. Her first contribution to lumbda was a
question — "do we care for our programs, and how long are they alive
for?" — and the answer now extends beyond the RNG portal (§7.5) to
iteration style itself.
Four-phase delivery, all under ticket 0004:
Phase A — idiomatic Scheme ports at examples/ursa-scheme.lsp.
Every Zoë defun rewritten as named-let + tail recursion + list-
backed work queue + type-predicate dispatch.
Phase B — CL compat shim at cl-compat.lsp.
defun (with &optional), setf (simple vars, multi-pair), flet,
multiple-value-bind, t / nil (nil=#f so cond/if compose),
evenp/oddp/plusp/minusp/zerop, mod/ash/logbitp/nreverse,
cl-when/cl-unless (plain when is a void-returning lumbda special
form), declare (no-op), cddddr (missing accessor).
Phase C — cl-loop macro covering 14 patterns.
while/until/repeat, for VAR from A to/below/downto B, for VAR =
INIT [then STEP], for VAR across VEC, of-type T, do, when/unless
return, finally (return VAL). Sequential do*-style stepping via
gensym + cl-subst. Look-ahead termination so `repeat 4 for s = 4
then (- (* s s) 2) finally (return s)` returns 37634 (pre-step)
rather than 1416317954 (post-step). Every expansion ends in a
named-let tail call — TCO holds for loops of any length.
Phase D — load examples/ursa.lisp.txt with minimal annotation.
Preserves Zoë's CL. Minimal edits documented in file header:
load cl-compat.lsp, loop→cl-loop, when→cl-when, random→random-int,
&key→&optional. rho/digits omitted (need make-array/CLOS — see
ticket 0004 for scope boundary).
Defect uncovered along the way (c/types.c env_lookup): a "global
shortcut" checked global env immediately after missing the local
frame, SKIPPING intermediate parent scopes. Broke lexical scoping
whenever a parent scope shadowed a global. Reproduced with
(define s 4)
(let ((s 100)) (let ((m 0)) s)) ; returned 4, should return 100
Any nested let whose body referenced a shadowed name silently read
the global. Fix: remove the shortcut, walk the parent chain end-to-
end. 1255 assertions across five suites pass unchanged after fix —
surfaced only because cl-loop iterator names routinely collide with
globals accumulated in a stone-lisp image.
Whitepaper §9.2 documents the CL-in-Scheme design and the guarantees
that survive (TCO, portal determinism, cross-impl reproducibility).
Zoë added to authors + acknowledgments; reacknowledgment reframes
her first contribution as the deeper program-lifetime question, with
RNG portal as a derivative (§7.5) and cl-loop as the follow-up.
Tests: tests/cl-compat.lsp (44 assertions) and tests/ursa.lsp (28
assertions) exercise both paths under Python + C via tests/zoe-
favorites-test.sh, wired into make test-all.
MOAD notes: unmoad flags memq/assq in cl-compat.lsp over cl-loop-
keywords (~30 elements, constant) and var->new (≤4 state vars per
loop). Both are macro-expansion-time, bounded-small-N — not runtime
hot paths. Pre-existing c/types.c findings (strcmp-in-loop for
record-type lookup) are not from this change.
248 lines
9.1 KiB
Makefile
248 lines
9.1 KiB
Makefile
# ═══════════════════════════════════════════════════════════════════
|
||
# lumbda — Python + C + Assembly implementations
|
||
# ═══════════════════════════════════════════════════════════════════
|
||
#
|
||
# Implementations:
|
||
# Python lumbda.py bytecode VM, full continuations, portal
|
||
# C c/lumbda tree-walker + bytecode VM + x86_64 JIT
|
||
# Assembly asm/lumbda pure x86_64, no libc, 13KB binary
|
||
#
|
||
# Test suites:
|
||
# make test Python unit/integration (571 tests)
|
||
# make c-test C unit/integration + JIT (76 tests) + functional (114)
|
||
# make asm-test Assembly unit/integration/functional (75 tests)
|
||
# make functional-test Shared .lsp suite in Python + C (114 each)
|
||
# make test-all Everything (836 total)
|
||
#
|
||
# Benchmarks (each generates reproducible numbers referenced in the
|
||
# whitepaper; hardware-independent commands, safety envelope built in):
|
||
# make bench Python bench.py (tree-walker vs bytecode VM)
|
||
# make c-bench C unit-level microbenchmarks
|
||
# make bench-3way §6.4: Python vs C vs asm on sum-to/ack
|
||
# make bench-portal §7.5: S-exp/JSON/binary portal save+load timings
|
||
# make bench-portal-cross §7.2: 3x3 cross-impl portal save×load matrix
|
||
# make bench-web §11.3: HTTP benchmark vs busybox + python http.server
|
||
# make bench-rpc-chain §11.4: Py → C relay → asm backend chain timing
|
||
# make bench-proof §8.6: EML proof — Lean 4 vs Lumbda tiers
|
||
# make bench-all run every bench above back to back
|
||
# make friction head-to-head timing: Python vs C vs CPython
|
||
#
|
||
# Other:
|
||
# make examples Run examples in Python + C, compare output
|
||
# make docs Generate architecture diagrams
|
||
# make whitepaper Build PDF whitepaper
|
||
# make clean-all Clean everything
|
||
|
||
all: test
|
||
|
||
# ─── Python implementation ────────────────────────────────────────
|
||
|
||
test:
|
||
python3 tests.py
|
||
|
||
test-verbose:
|
||
python3 tests.py -v
|
||
|
||
bench:
|
||
python3 bench.py
|
||
|
||
bench-verbose:
|
||
python3 bench.py -v
|
||
|
||
repl:
|
||
python3 lumbda.py
|
||
|
||
lint:
|
||
python3 -m py_compile lumbda.py
|
||
python3 -m py_compile tests.py
|
||
python3 -m py_compile bench.py
|
||
|
||
# ─── C implementation ─────────────────────────────────────────────
|
||
|
||
c-build:
|
||
$(MAKE) -C c all
|
||
|
||
c-test: c-build
|
||
$(MAKE) -C c test
|
||
@echo "── C functional tests (shared .lsp suite) ──"
|
||
./c/lumbda tests/functional.lsp
|
||
|
||
c-bench: c-build
|
||
$(MAKE) -C c bench
|
||
|
||
c-repl: c-build
|
||
./c/lumbda
|
||
|
||
c-clean:
|
||
$(MAKE) -C c clean
|
||
|
||
# ─── Assembly implementation ──────────────────────────────────────
|
||
|
||
asm-build:
|
||
$(MAKE) -C asm all
|
||
|
||
asm-test: asm-build
|
||
$(MAKE) -C asm test
|
||
|
||
asm-repl: asm-build
|
||
./asm/lumbda
|
||
|
||
asm-clean:
|
||
$(MAKE) -C asm clean
|
||
|
||
# ─── All implementations ─────────────────────────────────────────
|
||
|
||
functional-test: c-build
|
||
@echo "═══ Shared functional tests (114 tests) ═══"
|
||
@echo "── Python ──"
|
||
@python3 lumbda.py --fast tests/functional.lsp | tail -3
|
||
@echo "── C ──"
|
||
@./c/lumbda tests/functional.lsp | tail -3
|
||
|
||
portal-rng-cross-test: c-build asm-build
|
||
@bash tests/portal-rng-cross-test.sh
|
||
|
||
zoe-favorites-test: c-build
|
||
@bash tests/zoe-favorites-test.sh
|
||
|
||
test-all: test c-test asm-test functional-test portal-rng-cross-test zoe-favorites-test
|
||
@echo "════════════════════════════════════════════════════"
|
||
@echo "All tests passed (Python + C + Assembly + functional + portal-rng-cross + zoe-favorites)"
|
||
|
||
# ─── Benchmarks (reproducible; referenced in whitepaper §6–§11) ───
|
||
|
||
bench-3way: c-build asm-build
|
||
@bash tests/bench-3way.sh
|
||
|
||
bench-portal: c-build asm-build
|
||
@bash tests/portal-benchmark.sh
|
||
|
||
bench-portal-cross: c-build asm-build
|
||
@bash tests/portal-cross-test.sh
|
||
|
||
bench-web: c-build asm-build
|
||
@bash tests/web-benchmark.sh
|
||
|
||
bench-rpc-chain: c-build asm-build
|
||
@bash tests/rpc-chain-bench.sh
|
||
|
||
bench-proof: c-build asm-build
|
||
@bash tests/bench-proof.sh
|
||
|
||
bench-hashset: asm-build
|
||
@bash tests/bench-hashset.sh
|
||
|
||
bench-gc: asm-build
|
||
@bash tests/bench-gc-memory.sh
|
||
|
||
bench-gc-arena: asm-build
|
||
@bash tests/bench-gc-arena.sh
|
||
|
||
bench-gc-adaptive: asm-build
|
||
@bash tests/bench-gc-adaptive.sh
|
||
|
||
bench-gc-http: asm-build
|
||
@bash tests/bench-gc-http.sh
|
||
|
||
bench-lumbda-www: asm-build
|
||
@bash tests/bench-lumbda-www.sh
|
||
|
||
bench-www-race: asm-build
|
||
@bash tests/bench-www-race.sh
|
||
bench-all: bench c-bench bench-3way bench-portal bench-portal-cross bench-web bench-rpc-chain bench-proof
|
||
@echo "═══════════════════════════════════════════════════════════"
|
||
@echo "All benchmarks complete. Numbers in the whitepaper §6.4,"
|
||
@echo "§7.2, §7.5, §11.3, §11.4 are reproducible from these targets."
|
||
|
||
# ─── Examples ─────────────────────────────────────────────────────
|
||
|
||
examples: c-build
|
||
@echo "═══ fibonacci.lsp ═══"
|
||
@echo "--- Python ---" && python3 lumbda.py --fast examples/fibonacci.lsp
|
||
@echo "--- C ---" && ./c/lumbda examples/fibonacci.lsp
|
||
@echo
|
||
@echo "═══ mergesort.lsp ═══"
|
||
@echo "--- Python ---" && python3 lumbda.py --fast examples/mergesort.lsp
|
||
@echo "--- C ---" && ./c/lumbda examples/mergesort.lsp
|
||
@echo
|
||
@echo "═══ objects.lsp ═══"
|
||
@echo "--- Python ---" && python3 lumbda.py examples/objects.lsp
|
||
@echo "--- C ---" && ./c/lumbda examples/objects.lsp
|
||
|
||
# ─── Friction benchmark ──────────────────────────────────────────
|
||
|
||
friction: c-build asm-build
|
||
bash friction.sh
|
||
|
||
# ─── Documentation ────────────────────────────────────────────────
|
||
|
||
DOT_FILES := $(wildcard docs/*.dot)
|
||
DOT_PNGS := $(DOT_FILES:.dot=.png)
|
||
|
||
docs: $(DOT_PNGS)
|
||
|
||
docs/%.png: docs/%.dot
|
||
dot -Tpng $< -o $@
|
||
|
||
# ─── Whitepaper ───────────────────────────────────────────────────
|
||
|
||
VENV := whitepaper/.venv
|
||
RST := whitepaper/lumbda-whitepaper.rst
|
||
PDF := whitepaper/lumbda-whitepaper.pdf
|
||
HTML := whitepaper/lumbda-whitepaper.html
|
||
STYLE := whitepaper/whitepaper.style
|
||
|
||
$(VENV)/bin/rst2pdf:
|
||
python3 -m venv $(VENV)
|
||
$(VENV)/bin/pip install --upgrade pip
|
||
$(VENV)/bin/pip install rst2pdf docutils
|
||
|
||
whitepaper: $(PDF) $(HTML)
|
||
|
||
whitepaper-pdf: $(PDF)
|
||
whitepaper-html: $(HTML)
|
||
|
||
$(PDF): $(RST) $(STYLE) $(VENV)/bin/rst2pdf
|
||
cd whitepaper && ../$(<D)/.venv/bin/rst2pdf \
|
||
-s whitepaper.style \
|
||
--fit-background-mode=scale \
|
||
lumbda-whitepaper.rst \
|
||
-o lumbda-whitepaper.pdf
|
||
@ln -sf lumbda-whitepaper.pdf whitepaper/WHITEPAPER.pdf
|
||
@echo "Built: $(PDF)"
|
||
|
||
# HTML whitepaper: single self-contained file with embedded stylesheet
|
||
# plus an uncloseai.js module script (matches lumbda.com front door).
|
||
$(HTML): $(RST) $(VENV)/bin/rst2pdf
|
||
@DOCUTILS_CSS="$$(cd whitepaper/.venv/lib/python*/site-packages/docutils/writers/html5_polyglot && pwd)"; \
|
||
cd whitepaper && ../$(<D)/.venv/bin/rst2html5 \
|
||
--embed-stylesheet \
|
||
--stylesheet="$$DOCUTILS_CSS/minimal.css,$$DOCUTILS_CSS/responsive.css" \
|
||
lumbda-whitepaper.rst \
|
||
lumbda-whitepaper.html
|
||
@sed -i 's|</head>|<script src="https://uncloseai.com/uncloseai.js" type="module"></script>\n</head>|' $(HTML)
|
||
@sed -i 's|<title>lumbda-whitepaper.rst</title>|<title>Lumbda whitepaper — feedback as a primitive</title>|' $(HTML)
|
||
@python3 whitepaper/embed-images.py $(HTML)
|
||
@python3 whitepaper/inject-whitepaper-css.py $(HTML) \
|
||
www/fonts/chunkfive/chunkfive-regular-webfont.woff2
|
||
@echo "Built: $(HTML)"
|
||
|
||
# ─── Clean ────────────────────────────────────────────────────────
|
||
|
||
clean:
|
||
rm -rf __pycache__ *.pyc
|
||
|
||
clean-whitepaper:
|
||
rm -rf $(VENV) $(PDF) whitepaper/WHITEPAPER.pdf
|
||
|
||
clean-docs:
|
||
rm -f docs/*.png
|
||
|
||
clean-all: clean clean-whitepaper clean-docs c-clean asm-clean
|
||
|
||
.PHONY: all test test-verbose bench bench-verbose repl lint \
|
||
c-build c-test c-bench c-repl c-clean \
|
||
asm-build asm-test asm-repl asm-clean \
|
||
test-all bench-all examples friction functional-test portal-rng-cross-test \
|
||
bench-3way bench-portal bench-portal-cross bench-web bench-rpc-chain bench-proof \
|
||
docs whitepaper clean clean-whitepaper clean-docs clean-all
|