Find a file
russell@unturf.com 698a5d5f04
asm: gc_sweep page-fault on chunk-abandonment gap (segfault at chunk_end)
When heap_alloc walks off the end of a chunk with < 16 tail bytes,
.ha_grow_no_pad skips padding and mmaps a fresh chunk — but
gc_chunk_end[N] for the abandoned chunk stayed at its full mmap
end while %r15 (high-water) sat 1..15 bytes short. The gap held
mmap-zeros that gc_sweep's .gsw_walk decoded as fake dead blocks
(header == 0, payload size == 0, mark == 0). The walker stepped
through the zeros 8 bytes at a time, and on the iteration where
%rbx == chunk_end - 8 the .gsw_dead path stored the free-list
next-pointer to 0x8(%rbx) == chunk_end — the first byte of an
unmapped page — and segfaulted with error 7.

Reproducer (inside QEMU guest, was crashing all three asm
binaries):

  lumbda-full tests/unit/test-mod-solinas.lsp
  → segfault at <ptr ending 000> ip:4017d9
    (.gsw_dead: mov %rdx, 0x8(%rbx))

Fix: at .ha_grow_no_pad, snapshot %r15 into gc_chunk_end[N] before
allocating the new chunk. In the padded path above the label this
is a no-op (r15 already == r13). In the un-padded path it pins
the walk bound to the high-water mark so the sweep never enters
the gap.

After fix, on lumbda-full inside the ecdsa QEMU guest:
  - ecdsa test-mod-solinas: 39/39 PASS (Solinas vs Litinski
    byte-equal at p ∈ {11, 13, 251})
  - upstream asm test.sh: 158/158 PASS

Discovered while diagnosing ecdsa task #45.
2026-06-05 08:21:34 -04:00
asm asm: gc_sweep page-fault on chunk-abandonment gap (segfault at chunk_end) 2026-06-05 08:21:34 -04:00
c C tier: spawn-process-stdio + flush-port for bend cross-tier 2026-06-04 19:55:48 -04:00
docs ticket 0005: mark resolved, document the four bug fixes 2026-04-24 12:18:44 -04:00
examples examples/cuda-fanout: README — asm tier primitives landed 2026-06-04 20:41:34 -04:00
proof rename: uncommonlisp -> lumbda throughout the repo 2026-04-19 10:20:11 -04:00
tests c: enable Boehm GC by default, GC_INIT, file ops, regression test 2026-06-04 00:55:31 -04:00
whitepaper whitepaper: document the three asm tiers and five session-fixed defects 2026-04-24 12:52:59 -04:00
www Makefile + www: make gpu-worker target & start-worker docs 2026-06-05 08:19:51 -04:00
.gitignore Add whitepaper: Feedback Is All You Need 2026-04-14 13:32:42 -04:00
.gitlab-ci.yml www + whitepaper: adopt custom λ mark from MPS, green, 3× wordmark size 2026-04-19 17:32:43 -04:00
bench.py rename: uncommonlisp -> lumbda throughout the repo 2026-04-19 10:20:11 -04:00
cl-compat.lsp asm/lumbda-full: Zoë's CL runs end-to-end (ticket 0005 follow-up) 2026-04-24 12:17:58 -04:00
CLAUDE.md www: HTML whitepaper + prose rewrite avoiding "to be" and "the" 2026-04-19 16:23:56 -04:00
friction.sh rename: uncommonlisp -> lumbda throughout the repo 2026-04-19 10:20:11 -04:00
lumbda.py Python tier: spawn-process-stdio + flush-port; gpu-worker.lsp end-to-end 2026-06-04 19:36:15 -04:00
Makefile Makefile: rename GPU_WORKER_PORT → PORT to match docs 2026-06-05 08:20:16 -04:00
README.md rename: uncommonlisp -> lumbda throughout the repo 2026-04-19 10:20:11 -04:00
stdlib.lsp rename: uncommonlisp -> lumbda throughout the repo 2026-04-19 10:20:11 -04:00
tests.py rename followup: flip tests.py absolute path to /home/fox/git/lumbda 2026-04-19 10:29:51 -04:00

Lumbda

A Lisp/Scheme-derived, just-in-time lambda language. Four implementation tiers with MOAD defect isolation. Workloads migrate across basic UNIX systems.

Four implementation tiers sharing one wire format — Scheme source itself:

  • Python bytecode VM — reference, full first-class continuations
  • C tree-walker + bytecode VM — portable C, JSON portal
  • C + x86_64 JIT — pattern-matched native code, 710× faster than CPython
  • Pure x86_64 assembly — 22 KB stripped, zero libc, 14 syscalls

Feedback is the primitive across four scopes: continuations within a process, portal files across processes, S-expressions across implementations, TCP sockets across machines.

Home: lumbda.com

λ> (define (fib n)
     (let loop ((a 0) (b 1) (i 0))
       (if (= i n) a (loop b (+ a b) (+ i 1)))))
λ> (map fib (iota 10))
(0 1 1 2 3 5 8 13 21 34)

Usage

python3 lumbda.py                # interactive REPL
python3 lumbda.py script.lsp     # run a file
python3 lumbda.py -e '(+ 1 2)'  # eval an expression
python3 lumbda.py --fast script.lsp  # auto-compile (7-19x faster)

Bytecode compiler

Lumbda includes a stack-based bytecode compiler and VM. Enable it with --fast or (auto-compile! #t):

python3 lumbda.py --fast examples/fibonacci.lsp
(auto-compile! #t)
(define (ack m n)
  (cond ((= m 0) (+ n 1))
        ((= n 0) (ack (- m 1) 1))
        (else    (ack (- m 1) (ack m (- n 1))))))
(compiled? ack)  ; => #t
(ack 3 4)        ; => 125

The compiler handles: if, begin, and, or, when, unless, cond, define, set!, lambda, let, named-let, let*, letrec, do, call/cc, function calls with tail-call optimization. Macros are expanded at compile time. 20 specialized opcodes for hot builtins (+, -, *, =, <, car, cdr, cons, null?, etc.) avoid function call overhead.

Features:

  • Explicit frame stack — compiled-to-compiled calls don't grow the Python stack
  • Full continuationscall/cc supports upward continuations; generators work
  • Constant folding(+ 1 2) folds to 3 at compile time
  • Peephole optimizer — eliminates dead code (VOID+POP, JUMP-to-next)
  • (disassemble proc) — inspect generated bytecode

What's implemented

Core language

  • Full lexical scoping and closures
  • Tail-call optimization (TCO) — deep recursion never blows the stack
  • Hygienic macros via syntax-rules with ellipsis (...) support
  • define-macro / defmacro for procedural macros
  • call/cc — full continuations (escape + upward) in compiled code
  • values / call-with-values
  • dynamic-wind, guard, with-exception-handler
  • quasiquote / unquote / unquote-splicing with proper nesting
  • R7RS internal defines with letrec* body semantics
  • R7RS error objects
  • Exact rational arithmetic — (/ 1 3)1/3, (+ 1/4 3/4)1
  • String ports — open-input-string open-output-string read on ports
  • Mutable strings — string-set! string-fill! string-copy!
  • Module system — module / import with export lists
  • define-record-type with (inherit parent) for single-inheritance
  • Pretty-print — pp / pretty-print
  • Tracing — (trace fn) / (untrace fn)

Special forms define set! lambda λ if cond case and or when unless begin let let* letrec letrec* named-let do quasiquote define-macro define-syntax syntax-rules let-syntax letrec-syntax apply eval values call/cc dynamic-wind guard parameterize load error module import define-record-type

Built-ins

  • Arithmetic: + - * / quotient remainder modulo expt sqrt abs floor ceiling round truncate min max gcd lcm log exp trig functions, numerator denominator
  • Rationals: (/ 1 3)1/3, literal 1/3 syntax, exact / inexact conversion
  • Comparison: = < > <= >= zero? positive? negative? odd? even?
  • Pairs & lists: cons car cdr list length append reverse map for-each filter fold-left fold-right reduce any every sort partition find take drop zip flatten and more
  • SRFI-1: last firstfifth delete lset-union lset-intersection lset-difference unfold list-tabulate
  • Strings: string-length string-ref string-set! substring string-append string-copy string-copy! string-fill! string->list string->number format and more
  • Characters: char->integer integer->char char-alphabetic? char-upcase char-downcase
  • Vectors: make-vector vector vector-ref vector-set! vector-copy vector-copy!
  • Hash tables: make-hash-table hash-table-set! hash-table-ref hash-table-keys hash-table-values hash-table-walk and more
  • I/O: display write newline read read-char read-line open-input-string open-output-string with-output-to-string
  • File system: file-exists? delete-file rename-file directory-files current-directory
  • System: command-line get-environment-variable current-time exit
  • Python interop: py-eval py-exec py-import py-call py-attr
  • Compiler: compile compiled? disassemble auto-compile!

Standard library (stdlib.lsp) Additional macros, string/list/numeric/tree utilities, alist/hash helpers, simple object system, SRFI-2/8/64 test framework.

Examples

python3 lumbda.py --fast examples/fibonacci.lsp
python3 lumbda.py --fast examples/generator.lsp
python3 lumbda.py --fast examples/mergesort.lsp
python3 lumbda.py examples/objects.lsp
;; Generator using full continuations
(auto-compile! #t)
(define (make-gen thunk)
  (let ((k #f) (done #f))
    (lambda ()
      (if done 'done
          (call/cc (lambda (return)
            (if k (k return)
                (begin (thunk (lambda (val)
                         (call/cc (lambda (next)
                           (set! k next) (return val)))))
                       (set! done #t) (return 'done)))))))))

(define counter (make-gen (lambda (yield)
  (let loop ((i 0)) (yield i) (loop (+ i 1))))))
(counter) ; => 0
(counter) ; => 1
(counter) ; => 2

Running tests & benchmarks

make test          # run 529 tests
make test-verbose  # verbose output
make bench         # compare interpreter vs bytecode vs CPython
make lint          # syntax check all Python files

Portal — machine state migration

Serialize a running VM mid-computation, transfer to another machine, resume:

# Machine A: start a long computation with checkpoints
python3 lumbda.py --fast examples/portal-prime.lsp
# saves prime-state.portal at checkpoint

# Machine B: resume from checkpoint
python3 lumbda.py --portal-resume prime-state.portal
# continues from exact instruction

The portal captures the full env chain, compiled procedures, continuations, and frame stack as JSON. 16KB for a primality test in progress.

EML universality proof

The proof/ directory contains a formal verification that eml(x,y) = exp(x) - ln(y) with constant 1 generates all elementary functions (arXiv:2603.21852v2).

Three approaches, benchmarked:

Approach Time Guarantee
Python (numerical) 0.04s 1e-10 tolerance
Lumbda (numerical) 59s 1e-10 tolerance
Lean 4 (formal proof) 1.5s kernel-verified

The formal proof is 40x faster than brute-force search with infinitely stronger guarantees. See proof/benchmark_results.md for the full analysis — including why this is MOAD-0001 (the sedimentary defect) at the proof methodology layer.

File layout

lumbda.py   interpreter + bytecode compiler (one file, ~3200 lines)
stdlib.lsp        extended standard library
tests.py          test suite (571 tests)
bench.py          benchmarks vs CPython
examples/         example programs
proof/            EML universality proof (Python, Scheme, Lean 4)
Makefile          make test / make bench / make repl