Find a file
russell@unturf.com b890e3641f
C tier: spawn-process-stdio + flush-port for bend cross-tier
Two new primitives in builtins.c, paralleling the Python tier shipped in
the previous commit. gpu-worker.lsp now runs on the C tier byte-identically
to the Python tier.

  (spawn-process-stdio path args) → (stdin-port . stdout-port)
    fork + pipe + execvp; child's stdin & stdout wired back to parent
    as line-buffered FILE* ports. Accepts both strings and symbols in
    the args list (matches Python tier's permissive conversion).

  (flush-port port)
    fflush() on the port's FILE*. No-op when fp is null.

End-to-end on 3090-ai with C-tier lumbda everywhere:

  shell A:  ./lumbda /tmp/launch-c.lsp
            → gpu-worker: ready cuda-shake-fanout ← ./shake256-fanout
            → gpu-worker listening on port 9091

  shell B:  ./lumbda smoke-bend.lsp        # run 3×
            === smoke-bend ===
            1. cost estimator picks local for 3 inputs: OK
            2. worker available? #t
            3. bend! (cuda-shake-fanout '("00" "01" "deadbeef") 32):
               (b8d01df855… 94da6280b2… fa094fa86e…)

Three runs identical bytes. Same hashes as Python tier. Same hashes as
hashlib.shake_256 host reference.

Cross-tier matrix (proves wire protocol is tier-agnostic):

  client tier   worker tier   status
  ─────────────────────────────────────
  C tier        C tier        PASS — 2 sequential runs, byte-identical
  Python tier   C tier        PASS — same hashes
  C tier        Python tier   implicit by symmetry (same wire bytes
                              both directions; Python-server tested
                              against Python-client in prior commit)

Per-tier status after this commit:
  Python tier ✓ end-to-end
  C tier      ✓ end-to-end + cross-tier byte-identical to Python tier
  asm tier    → still needs spawn-process-stdio via raw fork+pipe+
                execve syscalls. Scheme files unchanged.
2026-06-04 19:55:48 -04:00
asm asm: case as always-on special form (defect #32) 2026-06-04 13:04: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 Python tier: spawn-process-stdio + flush-port; gpu-worker.lsp end-to-end 2026-06-04 19:36:15 -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 logo: revert artwork to source orientation (was over-flipped) 2026-04-19 17:42:14 -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 c: enable Boehm GC by default, GC_INIT, file ops, regression test 2026-06-04 00:55:31 -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