diff --git a/README.md b/README.md index 3a8fd5e..b6c4319 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,15 @@ # Lumbda -**A just-in-time lambda language — fast from first principles, workloads migratable across basic UNIX systems.** +**A Lisp/Scheme-derived, just-in-time lambda language. Four implementation tiers with EML mathematical universality and MOAD defect isolation. Workloads migrate across basic UNIX systems.** -Three implementations of R7RS Scheme (Python bytecode VM, C with x86_64 JIT, pure x86_64 assembly) sharing one wire format: Scheme source itself. Continuations within a process, portal files across processes, S-expressions across implementations, TCP sockets across machines. +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, 7–10× 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](https://lumbda.com) diff --git a/whitepaper/uncommonlisp-whitepaper.pdf b/whitepaper/uncommonlisp-whitepaper.pdf index 94d5569..86263f0 100644 --- a/whitepaper/uncommonlisp-whitepaper.pdf +++ b/whitepaper/uncommonlisp-whitepaper.pdf @@ -38,21 +38,21 @@ endobj << /A << /S /URI /Type /Action /URI (https://lumbda.com) ->> /Border [ 0 0 0 ] /Rect [ 184.2678 410.7477 238.7278 422.7477 ] /Subtype /Link /Type /Annot +>> /Border [ 0 0 0 ] /Rect [ 184.2678 398.7477 238.7278 410.7477 ] /Subtype /Link /Type /Annot >> endobj 8 0 obj << /A << /S /URI /Type /Action /URI (https://uncloseai.com) ->> /Border [ 0 0 0 ] /Rect [ 247.0678 410.7477 310.9778 422.7477 ] /Subtype /Link /Type /Annot +>> /Border [ 0 0 0 ] /Rect [ 247.0678 398.7477 310.9778 410.7477 ] /Subtype /Link /Type /Annot >> endobj 9 0 obj << /A << /S /URI /Type /Action /URI (https://www.permacomputer.com) ->> /Border [ 0 0 0 ] /Rect [ 319.3178 410.7477 411.0078 422.7477 ] /Subtype /Link /Type /Annot +>> /Border [ 0 0 0 ] /Rect [ 319.3178 398.7477 411.0078 410.7477 ] /Subtype /Link /Type /Annot >> endobj 10 0 obj @@ -494,7 +494,7 @@ endobj endobj 59 0 obj << -/Author () /CreationDate (D:20260417192222-04'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260417192222-04'00') /Producer (ReportLab PDF Library - \(opensource\)) +/Author () /CreationDate (D:20260417192647-04'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260417192647-04'00') /Producer (ReportLab PDF Library - \(opensource\)) /Subject (\(unspecified\)) /Title () /Trapped /False >> endobj @@ -510,54 +510,54 @@ endobj endobj 62 0 obj << -/Dest [ 11 0 R /XYZ 57.02362 346.4013 0 ] /Next 63 0 R /Parent 61 0 R /Title (Abstract) +/Dest [ 11 0 R /XYZ 57.02362 334.4013 0 ] /Next 63 0 R /Parent 61 0 R /Title (Abstract) >> endobj 63 0 obj << -/Dest [ 12 0 R /XYZ 57.02362 375.0236 0 ] /Next 64 0 R /Parent 61 0 R /Prev 62 0 R /Title (1. The Problem: Interpreters That Cannot Feed Back) +/Dest [ 12 0 R /XYZ 57.02362 273.0236 0 ] /Next 64 0 R /Parent 61 0 R /Prev 62 0 R /Title (1. The Problem: Interpreters That Cannot Feed Back) >> endobj 64 0 obj << -/Count 2 /Dest [ 12 0 R /XYZ 57.02362 167.8236 0 ] /First 65 0 R /Last 66 0 R /Next 67 0 R /Parent 61 0 R +/Count 2 /Dest [ 15 0 R /XYZ 57.02362 765.0236 0 ] /First 65 0 R /Last 66 0 R /Next 67 0 R /Parent 61 0 R /Prev 63 0 R /Title (2. Architecture: One File, Two Evaluators) >> endobj 65 0 obj << -/Dest [ 15 0 R /XYZ 57.02362 189.445 0 ] /Next 66 0 R /Parent 64 0 R /Title (2.1 Type System) +/Dest [ 15 0 R /XYZ 57.02362 160.245 0 ] /Next 66 0 R /Parent 64 0 R /Title (2.1 Type System) >> endobj 66 0 obj << -/Dest [ 16 0 R /XYZ 57.02362 655.0236 0 ] /Parent 64 0 R /Prev 65 0 R /Title (2.2 The Bytecode) +/Dest [ 16 0 R /XYZ 57.02362 619.0236 0 ] /Parent 64 0 R /Prev 65 0 R /Title (2.2 The Bytecode) >> endobj 67 0 obj << -/Dest [ 16 0 R /XYZ 57.02362 245.0236 0 ] /Next 68 0 R /Parent 61 0 R /Prev 64 0 R /Title (3. The Explicit Frame Stack) +/Dest [ 16 0 R /XYZ 57.02362 209.0236 0 ] /Next 68 0 R /Parent 61 0 R /Prev 64 0 R /Title (3. The Explicit Frame Stack) >> endobj 68 0 obj << -/Count 3 /Dest [ 17 0 R /XYZ 57.02362 566.6236 0 ] /First 69 0 R /Last 71 0 R /Next 72 0 R /Parent 61 0 R +/Count 3 /Dest [ 17 0 R /XYZ 57.02362 530.6236 0 ] /First 69 0 R /Last 71 0 R /Next 72 0 R /Parent 61 0 R /Prev 67 0 R /Title (4. Continuations: Feedback as a Data Structure) >> endobj 69 0 obj << -/Dest [ 17 0 R /XYZ 57.02362 159.0236 0 ] /Next 70 0 R /Parent 68 0 R /Title (4.1 Generators from Continuations) +/Dest [ 17 0 R /XYZ 57.02362 123.0236 0 ] /Next 70 0 R /Parent 68 0 R /Title (4.1 Generators from Continuations) >> endobj 70 0 obj << -/Dest [ 18 0 R /XYZ 57.02362 581.0236 0 ] /Next 71 0 R /Parent 68 0 R /Prev 69 0 R /Title (4.2 Why "Feedback Is All You Need") +/Dest [ 18 0 R /XYZ 57.02362 542.6236 0 ] /Next 71 0 R /Parent 68 0 R /Prev 69 0 R /Title (4.2 Why "Feedback Is All You Need") >> endobj 71 0 obj << -/Dest [ 18 0 R /XYZ 57.02362 363.0236 0 ] /Parent 68 0 R /Prev 70 0 R /Title (4.3 Four Scopes of Feedback) +/Dest [ 18 0 R /XYZ 57.02362 324.6236 0 ] /Parent 68 0 R /Prev 70 0 R /Title (4.3 Four Scopes of Feedback) >> endobj 72 0 obj @@ -697,7 +697,7 @@ endobj 98 0 obj << /Count 6 /Dest [ 33 0 R /XYZ 57.02362 555.0236 0 ] /First 99 0 R /Last 104 0 R /Next 105 0 R /Parent 61 0 R - /Prev 97 0 R /Title (11. Three Implementations, One Language) + /Prev 97 0 R /Title (11. Four Implementation Tiers, One Language) >> endobj 99 0 obj @@ -785,7 +785,7 @@ endobj endobj 115 0 obj << -/Length 4814 +/Length 4746 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET @@ -818,76 +818,76 @@ BT 1 0 0 1 0 3.2 Tm 213.9502 0 Td 19.2 TL /F2 16 Tf .133333 .133333 .133333 rg ( Q Q q -1 0 0 1 57.02362 476.7477 cm +1 0 0 1 57.02362 464.7477 cm q 0 0 0 rg -BT 1 0 0 1 0 14 Tm /F3 10 Tf 12 TL 2.214173 0 Td (A just-in-time lambda language \227 fast from first principles, workloads migratable across basic UNIX) Tj T* 217 0 Td (systems.) Tj T* -219.2142 0 Td ET +BT 1 0 0 1 0 26 Tm /F3 10 Tf 12 TL 25.84417 0 Td (A Lisp/Scheme-derived, just-in-time lambda language. Four implementation tiers with EML) Tj T* -4.184997 0 Td (mathematical universality and MOAD defect isolation. Workloads migrate across basic UNIX) Tj T* 197.555 0 Td (systems.) Tj T* -219.2142 0 Td ET Q Q q -1 0 0 1 57.02362 446.7477 cm +1 0 0 1 57.02362 434.7477 cm q 0 0 0 rg BT 1 0 0 1 0 14 Tm /F4 10 Tf 12 TL 7.189173 0 Td (Feedback is all you need: continuations within a process, portals across processes, S-expressions across) Tj T* 137.005 0 Td (implementations, sockets across machines.) Tj T* -144.1942 0 Td ET Q Q q -1 0 0 1 57.02362 428.7477 cm +1 0 0 1 57.02362 416.7477 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F4 10 Tf 12 TL 161.0692 0 Td (russell@unturf, TimeHexOn, foxhop) Tj T* -161.0692 0 Td ET Q Q q -1 0 0 1 57.02362 410.7477 cm +1 0 0 1 57.02362 398.7477 cm q BT 1 0 0 1 0 2 Tm 127.2442 0 Td 12 TL /F1 10 Tf 0 .4 .6 rg (lumbda.com) Tj 0 0 0 rg ( \267 ) Tj 0 .4 .6 rg (uncloseai.com) Tj 0 0 0 rg ( \267 ) Tj 0 .4 .6 rg (permacomputer.com) Tj T* -127.2442 0 Td ET Q Q q -1 0 0 1 57.02362 392.7477 cm +1 0 0 1 57.02362 380.7477 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F4 10 Tf 12 TL 218.1042 0 Td (April 2026) Tj T* -218.1042 0 Td ET Q Q q -1 0 0 1 57.02362 364.4013 cm +1 0 0 1 57.02362 352.4013 cm 0 0 0 RG n 0 14.17323 m 481.2283 14.17323 l S Q q -1 0 0 1 57.02362 333.2013 cm +1 0 0 1 57.02362 321.2013 cm q BT 1 0 0 1 0 2.2 Tm 13.2 TL /F2 11 Tf .133333 .133333 .133333 rg (Abstract) Tj T* ET Q Q q -1 0 0 1 57.02362 289.2013 cm +1 0 0 1 57.02362 277.2013 cm q BT 1 0 0 1 0 26 Tm -0.114777 Tw 12 TL /F3 10 Tf 0 0 0 rg (License: AGPL-3.0-only) Tj /F1 10 Tf ( \267 This implementation, its bytecode VM, & all associated code carry the GNU Affero) Tj T* 0 Tw 11.07917 0 Td (General Public License v3.0 \(only\). You may use, modify, & distribute under those terms. No proprietary) Tj T* 190.08 0 Td (relicensing exists.) Tj T* -201.1592 0 Td ET Q Q q -1 0 0 1 57.02362 235.2013 cm +1 0 0 1 57.02362 151.2013 cm q -BT 1 0 0 1 0 38 Tm 1.342739 Tw 12 TL /F1 10 Tf 0 0 0 rg (A programming language needs one primitive to become universal: feedback. A function that receives its) Tj T* 0 Tw .429882 Tw (own continuation can loop, branch, yield, checkpoint, resume, & migrate. Every control flow pattern reduces) Tj T* 0 Tw 2.216027 Tw (to a continuation captured & invoked. Extend feedback across time \(portals\) & across implementations) Tj T* 0 Tw (\(source-as-wire-format\) and you recover the full scope of computation without new primitives.) Tj T* ET +BT 1 0 0 1 0 110 Tm .779862 Tw 12 TL /F3 10 Tf 0 0 0 rg (Lumbda) Tj /F1 10 Tf ( is a Lisp/Scheme-derived language designed around two invariants that most languages discover) Tj T* 0 Tw 3.329862 Tw (late or never: ) Tj /F3 10 Tf (EML mathematical universality) Tj /F1 10 Tf ( \(every elementary function expressible from a single) Tj T* 0 Tw .114168 Tw (operator, machine-checked in Lean 4 \227 see \2478\) and ) Tj /F3 10 Tf (MOAD defect isolation) Tj /F1 10 Tf ( \(every implementation audited) Tj T* 0 Tw 5.643196 Tw (against the five canonical Mother-of-all-Defects patterns, with every defect confined to its own) Tj T* 0 Tw .140556 Tw (implementation tier rather than propagating through shared infrastructure \227 see \24712\). The rest of the design) Tj T* 0 Tw 2.900642 Tw (follows: one primitive, feedback, becomes universal when a function receives its own continuation. A) Tj T* 0 Tw 1.264168 Tw (continuation lets a program loop, branch, yield, checkpoint, resume, & migrate. Every control flow pattern) Tj T* 0 Tw 5.079873 Tw (reduces to a continuation captured & invoked. Extend feedback across time \(portals\) & across) Tj T* 0 Tw 3.784395 Tw (implementations \(source-as-wire-format\) and you recover the full scope of computation without new) Tj T* 0 Tw (primitives.) Tj T* ET Q Q q -1 0 0 1 57.02362 217.2013 cm +1 0 0 1 57.02362 121.2013 cm q -BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (Lumbda) Tj /F1 10 Tf ( proves this by implementing R7RS Scheme three ways:) Tj T* ET +BT 1 0 0 1 0 14 Tm .312025 Tw 12 TL /F1 10 Tf 0 0 0 rg (Lumbda ships in ) Tj /F3 10 Tf (four implementation tiers) Tj /F1 10 Tf ( \227 each independently built, each MOAD-isolated, each able to) Tj T* 0 Tw (run every test in the shared functional suite byte-identically:) Tj T* ET Q Q q -1 0 0 1 57.02362 211.2013 cm +1 0 0 1 57.02362 115.2013 cm Q q -1 0 0 1 57.02362 211.2013 cm +1 0 0 1 57.02362 115.2013 cm Q q -1 0 0 1 57.02362 187.2013 cm +1 0 0 1 57.02362 91.20126 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -909,10 +909,44 @@ Q Q Q q -1 0 0 1 57.02362 181.2013 cm +1 0 0 1 57.02362 85.20126 cm Q q -1 0 0 1 57.02362 157.2013 cm +1 0 0 1 57.02362 73.20126 cm +q +0 0 0 rg +BT /F1 10 Tf 12 TL ET +q +1 0 0 1 6 -3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F5 10 Tf 12 TL 8 0 Td (\177) Tj T* -8 0 Td ET +Q +Q +q +1 0 0 1 23 -3 cm +q +BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (C interpreter) Tj /F1 10 Tf ( \227 tree-walker + bytecode VM, 9,164 lines of runtime C, JSON portal) Tj T* ET +Q +Q +q +Q +Q +Q +q +1 0 0 1 57.02362 67.20126 cm +Q + +endstream +endobj +116 0 obj +<< +/Length 7878 +>> +stream +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +q +1 0 0 1 57.02362 741.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -926,7 +960,7 @@ Q q 1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 14 Tm .368241 Tw 12 TL /F3 10 Tf 0 0 0 rg (C interpreter + x86_64 JIT) Tj /F1 10 Tf ( \227 9,164 lines of runtime C \(plus ~1,200 in the test harness\), 7--10\327 faster) Tj T* 0 Tw (than CPython on recursive workloads, JSON portal) Tj T* ET +BT 1 0 0 1 0 14 Tm .876027 Tw 12 TL /F3 10 Tf 0 0 0 rg (C + x86_64 JIT) Tj /F1 10 Tf ( \227 pattern-matched native code emission via ) Tj /F5 10 Tf (mmap\(PROT_EXEC\)) Tj /F1 10 Tf (, 7--10\327 faster than) Tj T* 0 Tw (CPython on recursive workloads) Tj T* ET Q Q q @@ -934,10 +968,10 @@ Q Q Q q -1 0 0 1 57.02362 151.2013 cm +1 0 0 1 57.02362 735.0236 cm Q q -1 0 0 1 57.02362 127.2013 cm +1 0 0 1 57.02362 711.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -959,110 +993,95 @@ Q Q Q q -1 0 0 1 57.02362 109.2013 cm +1 0 0 1 57.02362 693.0236 cm Q q -1 0 0 1 57.02362 79.20126 cm +1 0 0 1 57.02362 639.0236 cm q -BT 1 0 0 1 0 14 Tm .814168 Tw 12 TL /F1 10 Tf 0 0 0 rg (All three share one interchange format: ) Tj /F3 10 Tf (Scheme source itself) Tj /F1 10 Tf (. An S-expression portal \() Tj /F5 10 Tf (\(define) Tj ( ) Tj (x) Tj ( ) Tj (42\)) Tj /F1 10 Tf (\)) Tj T* 0 Tw .689272 Tw (written by any implementation loads in any other \227 a 3\3273 producer\327consumer matrix, 9/9 cells green. The) Tj T* 0 Tw ET -Q -Q - -endstream -endobj -116 0 obj -<< -/Length 6685 ->> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 57.02362 741.0236 cm -q -BT 1 0 0 1 0 14 Tm .134417 Tw 12 TL /F1 10 Tf 0 0 0 rg (language ) Tj /F4 10 Tf (is) Tj /F1 10 Tf ( the wire protocol. This is not a property we added; it is what a parser has always made possible.) Tj T* 0 Tw (We report it because most systems forget.) Tj T* ET +BT 1 0 0 1 0 38 Tm .814168 Tw 12 TL /F1 10 Tf 0 0 0 rg (All three share one interchange format: ) Tj /F3 10 Tf (Scheme source itself) Tj /F1 10 Tf (. An S-expression portal \() Tj /F5 10 Tf (\(define) Tj ( ) Tj (x) Tj ( ) Tj (42\)) Tj /F1 10 Tf (\)) Tj T* 0 Tw .689272 Tw (written by any implementation loads in any other \227 a 3\3273 producer\327consumer matrix, 9/9 cells green. The) Tj T* 0 Tw .134417 Tw (language ) Tj /F4 10 Tf (is) Tj /F1 10 Tf ( the wire protocol. This is not a property we added; it is what a parser has always made possible.) Tj T* 0 Tw (We report it because most systems forget.) Tj T* ET Q Q q -1 0 0 1 57.02362 699.0236 cm +1 0 0 1 57.02362 597.0236 cm q BT 1 0 0 1 0 26 Tm 2.01589 Tw 12 TL /F3 10 Tf 0 0 0 rg (The numbers.) Tj /F1 10 Tf ( The asm implementation saves + resumes 4 variables across two processes in ) Tj /F3 10 Tf (1.5 ms) Tj /F1 10 Tf T* 0 Tw -0.051203 Tw (\(binary portal\) or ) Tj /F3 10 Tf (1.6 ms) Tj /F1 10 Tf ( \(S-expression portal\). Python round-trip on the same task: 260 ms. A 160\327 gap from) Tj T* 0 Tw (the same language, same tests, same wire format.) Tj T* ET Q Q q -1 0 0 1 57.02362 621.0236 cm +1 0 0 1 57.02362 519.0236 cm q BT 1 0 0 1 0 62 Tm 3.009029 Tw 12 TL /F3 10 Tf 0 0 0 rg (Web server, same story.) Tj /F1 10 Tf ( The asm implementation ships a TCP stack \() Tj /F5 10 Tf (tcp-listen) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (tcp-accept) Tj /F1 10 Tf (,) Tj T* 0 Tw 1.01985 Tw /F5 10 Tf (tcp-connect) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (tcp-recv) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (tcp-send) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (tcp-close) Tj /F1 10 Tf (\) and a portable 70-line HTTP/1.0 handler in Scheme.) Tj T* 0 Tw .40135 Tw (The same ) Tj /F5 10 Tf (.lsp) Tj /F1 10 Tf ( runs identically in all three impls. Asm server + asm client: ) Tj /F3 10 Tf (2,994 req/s) Tj /F1 10 Tf ( on a 1 KB body, 22) Tj T* 0 Tw 1.003647 Tw (KB binary, zero libc, seven Linux syscalls plus the socket family. For comparison: busybox httpd \(2.1 MB\)) Tj T* 0 Tw .109314 Tw (and ) Tj /F5 10 Tf (python3) Tj ( ) Tj (-m) Tj ( ) Tj (http.server) Tj /F1 10 Tf ( \(8 MB interpreter\) hit the same benchmark at 382 req/s under a curl client) Tj T* 0 Tw (and ~2,400 req/s under an in-process client.) Tj T* ET Q Q q -1 0 0 1 57.02362 543.0236 cm +1 0 0 1 57.02362 441.0236 cm q BT 1 0 0 1 0 62 Tm 3.182556 Tw 12 TL /F3 10 Tf 0 0 0 rg (S-expressions over sockets.) Tj /F1 10 Tf ( The wire protocol for a 90-line RPC server is one Scheme form per) Tj T* 0 Tw 1.692397 Tw (connection. With ) Tj /F5 10 Tf (read-from-string) Tj /F1 10 Tf ( and ) Tj /F5 10 Tf (eval) Tj /F1 10 Tf ( added to all three impls \(89 bytes of asm for ) Tj /F5 10 Tf (eval) Tj /F1 10 Tf (, a) Tj T* 0 Tw .615304 Tw (20-line asm reader swap for ) Tj /F5 10 Tf (read-from-string) Tj /F1 10 Tf (\), a transparent byte-forwarding relay composes arbitrary) Tj T* 0 Tw -0.093771 Tw (chains: a Python client can reach an asm backend through a C relay and a Python relay, four runtimes strung) Tj T* 0 Tw .231223 Tw (together without any format translation between hops. Each relay adds ~650 \265s/request on the same laptop.) Tj T* 0 Tw (The language is the envelope.) Tj T* ET Q Q q -1 0 0 1 57.02362 489.0236 cm +1 0 0 1 57.02362 387.0236 cm q BT 1 0 0 1 0 38 Tm 1.342739 Tw 12 TL /F1 10 Tf 0 0 0 rg (975 verified assertions pass identically across the three implementations \(571 Python unit, 132 asm, 189) Tj T* 0 Tw 3.349873 Tw (shared Python+C functional, 83 C unit\). Every implementation consumes every format it can reach;) Tj T* 0 Tw .270556 Tw (mismatch cases \(wrong format, truncated input, missing file, corrupt header\) degrade gracefully with ) Tj /F5 10 Tf (#f) Tj /F1 10 Tf ( or a) Tj T* 0 Tw (clean error.) Tj T* ET Q Q q -1 0 0 1 57.02362 435.0236 cm +1 0 0 1 57.02362 333.0236 cm q BT 1 0 0 1 0 38 Tm .352397 Tw 12 TL /F1 10 Tf 0 0 0 rg (The paper further presents the EML universality proof: a single operator ) Tj /F5 10 Tf (eml\(x,) Tj ( ) Tj (y\)) Tj ( ) Tj (=) Tj ( ) Tj (exp\(x\)) Tj ( ) Tj (-) Tj ( ) Tj (ln\(y\)) Tj /F1 10 Tf T* 0 Tw .548453 Tw (with the constant 1 generates all elementary functions \(exp, ln, arithmetic, negation, complex plane access,) Tj T* 0 Tw -0.05811 Tw (trigonometry\). Verified numerically in Python, verified in Lumbda's own bytecode, & proven formally in Lean 4) Tj T* 0 Tw (with zero ) Tj /F5 10 Tf (sorry) Tj /F1 10 Tf (.) Tj T* ET Q Q q -1 0 0 1 57.02362 393.0236 cm +1 0 0 1 57.02362 291.0236 cm q 0 0 0 rg BT 1 0 0 1 0 26 Tm /F1 10 Tf 12 TL .70189 Tw (Feedback is the primitive. Continuations are its mechanism in time. Portals are its mechanism across time.) Tj T* 0 Tw -0.095138 Tw (S-expressions are its mechanism across implementations. Sockets are its mechanism across machines. One) Tj T* 0 Tw (file is the proof \227 by three translations.) Tj T* ET Q Q q -1 0 0 1 57.02362 361.8236 cm +1 0 0 1 57.02362 259.8236 cm q BT 1 0 0 1 0 2.2 Tm 13.2 TL /F2 11 Tf .133333 .133333 .133333 rg (1. The Problem: Interpreters That Cannot Feed Back) Tj T* ET Q Q q -1 0 0 1 57.02362 293.8236 cm +1 0 0 1 57.02362 191.8236 cm q BT 1 0 0 1 0 50 Tm 1.454556 Tw 12 TL /F1 10 Tf 0 0 0 rg (Most language implementations treat control flow as a tree of special cases. ) Tj /F5 10 Tf (if) Tj /F1 10 Tf ( branches. ) Tj /F5 10 Tf (while) Tj /F1 10 Tf ( loops.) Tj T* 0 Tw .47989 Tw /F5 10 Tf (return) Tj /F1 10 Tf ( exits. ) Tj /F5 10 Tf (try/catch) Tj /F1 10 Tf ( unwinds. Each form carries its own implementation, its own edge cases, its own) Tj T* 0 Tw 1.451147 Tw (interaction with the call stack. When you need a pattern that crosses these boundaries \(a generator that) Tj T* 0 Tw 3.669873 Tw (yields mid-loop, a coroutine that resumes from a checkpoint, a computation that migrates between) Tj T* 0 Tw (machines\), the tower of special cases collapses.) Tj T* ET Q Q q -1 0 0 1 57.02362 239.8236 cm +1 0 0 1 57.02362 137.8236 cm q BT 1 0 0 1 0 38 Tm .104917 Tw 12 TL /F1 10 Tf 0 0 0 rg (The insight: every control flow pattern is a special case of feedback. A loop feeds the tail position back to the) Tj T* 0 Tw 1.658797 Tw (head. A generator feeds a value out & a resumption point in. An exception feeds control to the nearest) Tj T* 0 Tw 1.518647 Tw (handler. A checkpoint feeds the entire machine state to storage. If the language exposes feedback as a) Tj T* 0 Tw (first-class primitive, all these patterns compose without special cases.) Tj T* ET Q Q q -1 0 0 1 57.02362 185.8236 cm +1 0 0 1 57.02362 83.82362 cm q BT 1 0 0 1 0 38 Tm 5.742038 Tw 12 TL /F1 10 Tf 0 0 0 rg (Scheme discovered this in 1975 with ) Tj /F5 10 Tf (call-with-current-continuation) Tj /F1 10 Tf (. But most Scheme) Tj T* 0 Tw .086835 Tw (implementations compromise: they limit continuations to escape-only, implement them via ) Tj /F5 10 Tf (setjmp) Tj /F1 10 Tf (/) Tj /F5 10 Tf (longjmp) Tj /F1 10 Tf T* 0 Tw .712256 Tw (on the C stack, or require CPS transformation that obscures the source. Lumbda takes a different path: an) Tj T* 0 Tw (explicit frame stack that makes continuations a data structure, not a stack manipulation trick.) Tj T* ET Q Q -q -1 0 0 1 57.02362 154.6236 cm -q -BT 1 0 0 1 0 2.2 Tm 13.2 TL /F2 11 Tf .133333 .133333 .133333 rg (2. Architecture: One File, Two Evaluators) Tj T* ET -Q -Q -q -1 0 0 1 57.02362 138.6236 cm -Q endstream endobj 117 0 obj << -/Length 5277 +/Length 4740 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 57.02362 367.445 cm +1 0 0 1 57.02362 751.8236 cm +q +BT 1 0 0 1 0 2.2 Tm 13.2 TL /F2 11 Tf .133333 .133333 .133333 rg (2. Architecture: One File, Two Evaluators) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 735.8236 cm +Q +q +1 0 0 1 57.02362 338.245 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1085,54 +1104,54 @@ Q Q Q q -1 0 0 1 57.02362 359.445 cm +1 0 0 1 57.02362 330.245 cm Q q -1 0 0 1 57.02362 341.445 cm +1 0 0 1 57.02362 312.245 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Lumbda implements two evaluation strategies in a single 3,743-line Python file:) Tj T* ET Q Q q -1 0 0 1 57.02362 299.445 cm +1 0 0 1 57.02362 270.245 cm q BT 1 0 0 1 0 26 Tm 1.151411 Tw 12 TL /F3 10 Tf 0 0 0 rg (Tree-walking interpreter) Tj /F1 10 Tf ( \() Tj /F5 10 Tf (leval) Tj /F1 10 Tf (\): The default mode. Walks the AST directly, handles all forms including) Tj T* 0 Tw 3.328196 Tw (macro definitions, record types, & dynamic features. Suitable for interactive development & complex) Tj T* 0 Tw (metaprogramming.) Tj T* ET Q Q q -1 0 0 1 57.02362 257.445 cm +1 0 0 1 57.02362 228.245 cm q BT 1 0 0 1 0 26 Tm .557565 Tw 12 TL /F3 10 Tf 0 0 0 rg (Bytecode compiler + VM) Tj /F1 10 Tf ( \() Tj /F5 10 Tf (_bc) Tj /F1 10 Tf ( + ) Tj /F5 10 Tf (_vm_loop) Tj /F1 10 Tf (\): Enabled with ) Tj /F5 10 Tf (--fast) Tj /F1 10 Tf ( or ) Tj /F5 10 Tf (\(auto-compile!) Tj ( ) Tj (#t\)) Tj /F1 10 Tf (. Compiles) Tj T* 0 Tw .84589 Tw (Scheme expressions to a stack-based bytecode, then executes on a virtual machine with an explicit frame) Tj T* 0 Tw (stack. Achieves 7--19x speedups on recursive & iterative workloads.) Tj T* ET Q Q q -1 0 0 1 57.02362 203.445 cm +1 0 0 1 57.02362 174.245 cm q BT 1 0 0 1 0 38 Tm 1.065596 Tw 12 TL /F1 10 Tf 0 0 0 rg (Both evaluators share the same type system, environment model, & built-in function library. The bytecode) Tj T* 0 Tw 1.668334 Tw (compiler handles: ) Tj /F5 10 Tf (if) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (begin) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (and) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (or) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (when) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (unless) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (cond) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (define) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (set!) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (lambda) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (let) Tj /F1 10 Tf (, named-let,) Tj T* 0 Tw 1.459882 Tw /F5 10 Tf (let*) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (letrec) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (do) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (call/cc) Tj /F1 10 Tf (, & function calls with tail-call optimization. Macros expand at compile time.) Tj T* 0 Tw (Forms the compiler cannot handle fall back to the interpreter via ) Tj /F5 10 Tf (OP_EVAL) Tj /F1 10 Tf (.) Tj T* ET Q Q q -1 0 0 1 57.02362 177.445 cm +1 0 0 1 57.02362 148.245 cm q BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (2.1 Type System) Tj T* ET Q Q q -1 0 0 1 57.02362 159.445 cm +1 0 0 1 57.02362 130.245 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Core types stay minimal:) Tj T* ET Q Q q -1 0 0 1 57.02362 153.445 cm +1 0 0 1 57.02362 124.245 cm Q q -1 0 0 1 57.02362 153.445 cm +1 0 0 1 57.02362 124.245 cm Q q -1 0 0 1 57.02362 141.445 cm +1 0 0 1 57.02362 112.245 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1154,10 +1173,10 @@ Q Q Q q -1 0 0 1 57.02362 135.445 cm +1 0 0 1 57.02362 106.245 cm Q q -1 0 0 1 57.02362 123.445 cm +1 0 0 1 57.02362 94.24503 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1179,10 +1198,10 @@ Q Q Q q -1 0 0 1 57.02362 117.445 cm +1 0 0 1 57.02362 88.24503 cm Q q -1 0 0 1 57.02362 105.445 cm +1 0 0 1 57.02362 76.24503 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1204,64 +1223,14 @@ Q Q Q q -1 0 0 1 57.02362 99.44503 cm -Q -q -1 0 0 1 57.02362 87.44503 cm -q -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F5 10 Tf 12 TL 8 0 Td (\177) Tj T* -8 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (Proc) Tj /F1 10 Tf (: Interpreted procedure \(params, rest, body, env, name\)) Tj T* ET -Q -Q -q -Q -Q -Q -q -1 0 0 1 57.02362 81.44503 cm -Q -q -1 0 0 1 57.02362 69.44503 cm -q -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F5 10 Tf 12 TL 8 0 Td (\177) Tj T* -8 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (CompiledProc) Tj /F1 10 Tf (: Bytecode procedure \(CodeObj, params, rest, env, name\)) Tj T* ET -Q -Q -q -Q -Q -Q -q -1 0 0 1 57.02362 63.44503 cm +1 0 0 1 57.02362 70.24503 cm Q endstream endobj 118 0 obj << -/Length 6896 +/Length 6876 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET @@ -1280,7 +1249,7 @@ Q q 1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (FullCont) Tj /F1 10 Tf (: First-class continuation \(frames, stack, ip, instrs, env, vm_id\)) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (Proc) Tj /F1 10 Tf (: Interpreted procedure \(params, rest, body, env, name\)) Tj T* ET Q Q q @@ -1305,7 +1274,7 @@ Q q 1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (Macro) Tj /F1 10 Tf (: Wraps a transformer \(Proc or _SyntaxTransformer\)) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (CompiledProc) Tj /F1 10 Tf (: Bytecode procedure \(CodeObj, params, rest, env, name\)) Tj T* ET Q Q q @@ -1330,6 +1299,56 @@ Q q 1 0 0 1 23 -3 cm q +BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (FullCont) Tj /F1 10 Tf (: First-class continuation \(frames, stack, ip, instrs, env, vm_id\)) Tj T* ET +Q +Q +q +Q +Q +Q +q +1 0 0 1 57.02362 711.0236 cm +Q +q +1 0 0 1 57.02362 699.0236 cm +q +0 0 0 rg +BT /F1 10 Tf 12 TL ET +q +1 0 0 1 6 -3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F5 10 Tf 12 TL 8 0 Td (\177) Tj T* -8 0 Td ET +Q +Q +q +1 0 0 1 23 -3 cm +q +BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (Macro) Tj /F1 10 Tf (: Wraps a transformer \(Proc or _SyntaxTransformer\)) Tj T* ET +Q +Q +q +Q +Q +Q +q +1 0 0 1 57.02362 693.0236 cm +Q +q +1 0 0 1 57.02362 681.0236 cm +q +0 0 0 rg +BT /F1 10 Tf 12 TL ET +q +1 0 0 1 6 -3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F5 10 Tf 12 TL 8 0 Td (\177) Tj T* -8 0 Td ET +Q +Q +q +1 0 0 1 23 -3 cm +q BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (Env) Tj /F1 10 Tf (: Lexical environment chain \(bindings dict, parent pointer, global pointer\)) Tj T* ET Q Q @@ -1338,34 +1357,34 @@ Q Q Q q -1 0 0 1 57.02362 699.0236 cm +1 0 0 1 57.02362 663.0236 cm Q q -1 0 0 1 57.02362 669.0236 cm +1 0 0 1 57.02362 633.0236 cm q BT 1 0 0 1 0 14 Tm .618556 Tw 12 TL /F1 10 Tf 0 0 0 rg (Exact rational arithmetic uses Python's ) Tj /F5 10 Tf (Fraction) Tj /F1 10 Tf ( type. ) Tj /F5 10 Tf (\(/) Tj ( ) Tj (1) Tj ( ) Tj (3\)) Tj /F1 10 Tf ( evaluates to ) Tj /F5 10 Tf (1/3) Tj /F1 10 Tf (, not ) Tj /F5 10 Tf (0.333...) Tj /F1 10 Tf (. Literal) Tj T* 0 Tw /F5 10 Tf (1/3) Tj /F1 10 Tf ( syntax parses directly to rationals.) Tj T* ET Q Q q -1 0 0 1 57.02362 643.0236 cm +1 0 0 1 57.02362 607.0236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (2.2 The Bytecode) Tj T* ET Q Q q -1 0 0 1 57.02362 625.0236 cm +1 0 0 1 57.02362 589.0236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (The compiler emits instructions as ) Tj /F5 10 Tf (\(opcode,) Tj ( ) Tj (operand\)) Tj /F1 10 Tf ( tuples into a ) Tj /F5 10 Tf (CodeObj) Tj /F1 10 Tf (:) Tj T* ET Q Q q -1 0 0 1 57.02362 607.0236 cm +1 0 0 1 57.02362 571.0236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (Core opcodes) Tj /F1 10 Tf ( \(20\):) Tj T* ET Q Q q -1 0 0 1 57.02362 393.8236 cm +1 0 0 1 57.02362 357.8236 cm q q 1 0 0 1 0 0 cm @@ -1385,13 +1404,13 @@ Q Q Q q -1 0 0 1 57.02362 373.8236 cm +1 0 0 1 57.02362 337.8236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (Specialized opcodes) Tj /F1 10 Tf ( \(20\):) Tj T* ET Q Q q -1 0 0 1 57.02362 295.0236 cm +1 0 0 1 57.02362 259.0236 cm q q 1 0 0 1 0 0 cm @@ -1412,33 +1431,33 @@ Q Q Q q -1 0 0 1 57.02362 263.0236 cm +1 0 0 1 57.02362 227.0236 cm q BT 1 0 0 1 0 14 Tm .370522 Tw 12 TL /F1 10 Tf 0 0 0 rg (Specialized opcodes avoid function call overhead for hot builtins. ) Tj /F5 10 Tf (\(+) Tj ( ) Tj (x) Tj ( ) Tj (1\)) Tj /F1 10 Tf ( compiles to ) Tj /F5 10 Tf (OP_ADD1) Tj /F1 10 Tf ( instead of) Tj T* 0 Tw /F5 10 Tf (OP_LOOKUP) Tj ( ) Tj ('+') Tj ( ) Tj (/) Tj ( ) Tj (OP_CONST) Tj ( ) Tj (1) Tj ( ) Tj (/) Tj ( ) Tj (OP_CALL) Tj /F1 10 Tf (.) Tj T* ET Q Q q -1 0 0 1 57.02362 231.8236 cm +1 0 0 1 57.02362 195.8236 cm q BT 1 0 0 1 0 2.2 Tm 13.2 TL /F2 11 Tf .133333 .133333 .133333 rg (3. The Explicit Frame Stack) Tj T* ET Q Q q -1 0 0 1 57.02362 211.8236 cm +1 0 0 1 57.02362 175.8236 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (This is the architectural decision that makes everything else possible.) Tj T* ET Q Q q -1 0 0 1 57.02362 193.8236 cm +1 0 0 1 57.02362 157.8236 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Instead of using Python's call stack for Scheme function calls, the VM maintains its own frame stack:) Tj T* ET Q Q q -1 0 0 1 57.02362 163.0236 cm +1 0 0 1 57.02362 127.0236 cm q q 1 0 0 1 0 0 cm @@ -1459,19 +1478,19 @@ Q Q Q q -1 0 0 1 57.02362 143.0236 cm +1 0 0 1 57.02362 107.0236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (When ) Tj /F5 10 Tf (OP_CALL) Tj /F1 10 Tf ( executes:) Tj T* ET Q Q q -1 0 0 1 57.02362 137.0236 cm +1 0 0 1 57.02362 101.0236 cm Q q -1 0 0 1 57.02362 137.0236 cm +1 0 0 1 57.02362 101.0236 cm Q q -1 0 0 1 57.02362 125.0236 cm +1 0 0 1 57.02362 89.02362 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1494,10 +1513,10 @@ Q Q Q q -1 0 0 1 57.02362 119.0236 cm +1 0 0 1 57.02362 83.02362 cm Q q -1 0 0 1 57.02362 107.0236 cm +1 0 0 1 57.02362 71.02362 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1519,10 +1538,19 @@ Q Q Q q -1 0 0 1 57.02362 101.0236 cm +1 0 0 1 57.02362 65.02362 cm Q + +endstream +endobj +119 0 obj +<< +/Length 8861 +>> +stream +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 57.02362 89.02362 cm +1 0 0 1 57.02362 753.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1544,10 +1572,10 @@ Q Q Q q -1 0 0 1 57.02362 83.02362 cm +1 0 0 1 57.02362 747.0236 cm Q q -1 0 0 1 57.02362 71.02362 cm +1 0 0 1 57.02362 735.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1570,19 +1598,10 @@ Q Q Q q -1 0 0 1 57.02362 65.02362 cm +1 0 0 1 57.02362 729.0236 cm Q - -endstream -endobj -119 0 obj -<< -/Length 8468 ->> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 57.02362 753.0236 cm +1 0 0 1 57.02362 717.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1605,22 +1624,22 @@ Q Q Q q -1 0 0 1 57.02362 753.0236 cm +1 0 0 1 57.02362 717.0236 cm Q q -1 0 0 1 57.02362 735.0236 cm +1 0 0 1 57.02362 699.0236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (When ) Tj /F5 10 Tf (OP_RETURN) Tj /F1 10 Tf ( executes:) Tj T* ET Q Q q -1 0 0 1 57.02362 729.0236 cm +1 0 0 1 57.02362 693.0236 cm Q q -1 0 0 1 57.02362 729.0236 cm +1 0 0 1 57.02362 693.0236 cm Q q -1 0 0 1 57.02362 717.0236 cm +1 0 0 1 57.02362 681.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1642,10 +1661,10 @@ Q Q Q q -1 0 0 1 57.02362 711.0236 cm +1 0 0 1 57.02362 675.0236 cm Q q -1 0 0 1 57.02362 699.0236 cm +1 0 0 1 57.02362 663.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1667,16 +1686,16 @@ Q Q Q q -1 0 0 1 57.02362 699.0236 cm +1 0 0 1 57.02362 663.0236 cm Q q -1 0 0 1 57.02362 669.0236 cm +1 0 0 1 57.02362 633.0236 cm q BT 1 0 0 1 0 14 Tm 2.331529 Tw 12 TL /F3 10 Tf 0 0 0 rg (Tail-call optimization) Tj /F1 10 Tf ( follows naturally: ) Tj /F5 10 Tf (OP_TAIL_CALL) Tj /F1 10 Tf ( skips step 2. It replaces the current activation) Tj T* 0 Tw (record instead of pushing a new one. Tail-recursive loops of arbitrary depth consume constant memory.) Tj T* ET Q Q q -1 0 0 1 57.02362 628.6236 cm +1 0 0 1 57.02362 592.6236 cm q q 1 0 0 1 0 0 cm @@ -1697,26 +1716,26 @@ Q Q Q q -1 0 0 1 57.02362 584.6236 cm +1 0 0 1 57.02362 548.6236 cm q BT 1 0 0 1 0 26 Tm .144609 Tw 12 TL /F3 10 Tf 0 0 0 rg (Why this matters) Tj /F1 10 Tf (: Python's default recursion limit is 1,000 frames. A Scheme that uses the Python stack for) Tj T* 0 Tw -0.073228 Tw (Scheme calls inherits this limit. The explicit frame stack removes it. Lumbda can recurse 50,000 deep without) Tj T* 0 Tw (difficulty, limited only by available memory.) Tj T* ET Q Q q -1 0 0 1 57.02362 553.4236 cm +1 0 0 1 57.02362 517.4236 cm q BT 1 0 0 1 0 2.2 Tm 13.2 TL /F2 11 Tf .133333 .133333 .133333 rg (4. Continuations: Feedback as a Data Structure) Tj T* ET Q Q q -1 0 0 1 57.02362 533.4236 cm +1 0 0 1 57.02362 497.4236 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (With an explicit frame stack, capturing a continuation becomes copying a data structure:) Tj T* ET Q Q q -1 0 0 1 57.02362 445.0236 cm +1 0 0 1 57.02362 409.0236 cm q q 1 0 0 1 0 0 cm @@ -1737,19 +1756,19 @@ Q Q Q q -1 0 0 1 57.02362 425.0236 cm +1 0 0 1 57.02362 389.0236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (When ) Tj /F5 10 Tf (OP_CALL_CC) Tj /F1 10 Tf ( executes:) Tj T* ET Q Q q -1 0 0 1 57.02362 419.0236 cm +1 0 0 1 57.02362 383.0236 cm Q q -1 0 0 1 57.02362 419.0236 cm +1 0 0 1 57.02362 383.0236 cm Q q -1 0 0 1 57.02362 395.0236 cm +1 0 0 1 57.02362 359.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1771,10 +1790,10 @@ Q Q Q q -1 0 0 1 57.02362 389.0236 cm +1 0 0 1 57.02362 353.0236 cm Q q -1 0 0 1 57.02362 377.0236 cm +1 0 0 1 57.02362 341.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1796,10 +1815,10 @@ Q Q Q q -1 0 0 1 57.02362 371.0236 cm +1 0 0 1 57.02362 335.0236 cm Q q -1 0 0 1 57.02362 359.0236 cm +1 0 0 1 57.02362 323.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1821,10 +1840,10 @@ Q Q Q q -1 0 0 1 57.02362 353.0236 cm +1 0 0 1 57.02362 317.0236 cm Q q -1 0 0 1 57.02362 341.0236 cm +1 0 0 1 57.02362 305.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1846,10 +1865,10 @@ Q Q Q q -1 0 0 1 57.02362 335.0236 cm +1 0 0 1 57.02362 299.0236 cm Q q -1 0 0 1 57.02362 323.0236 cm +1 0 0 1 57.02362 287.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1872,23 +1891,23 @@ Q Q Q q -1 0 0 1 57.02362 323.0236 cm +1 0 0 1 57.02362 287.0236 cm Q q -1 0 0 1 57.02362 305.0236 cm +1 0 0 1 57.02362 269.0236 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (When a continuation is invoked:) Tj T* ET Q Q q -1 0 0 1 57.02362 299.0236 cm +1 0 0 1 57.02362 263.0236 cm Q q -1 0 0 1 57.02362 299.0236 cm +1 0 0 1 57.02362 263.0236 cm Q q -1 0 0 1 57.02362 287.0236 cm +1 0 0 1 57.02362 251.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1910,10 +1929,10 @@ Q Q Q q -1 0 0 1 57.02362 281.0236 cm +1 0 0 1 57.02362 245.0236 cm Q q -1 0 0 1 57.02362 269.0236 cm +1 0 0 1 57.02362 233.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1935,10 +1954,10 @@ Q Q Q q -1 0 0 1 57.02362 263.0236 cm +1 0 0 1 57.02362 227.0236 cm Q q -1 0 0 1 57.02362 251.0236 cm +1 0 0 1 57.02362 215.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1960,10 +1979,10 @@ Q Q Q q -1 0 0 1 57.02362 245.0236 cm +1 0 0 1 57.02362 209.0236 cm Q q -1 0 0 1 57.02362 233.0236 cm +1 0 0 1 57.02362 197.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1986,10 +2005,10 @@ Q Q Q q -1 0 0 1 57.02362 227.0236 cm +1 0 0 1 57.02362 191.0236 cm Q q -1 0 0 1 57.02362 215.0236 cm +1 0 0 1 57.02362 179.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -2012,57 +2031,37 @@ Q Q Q q -1 0 0 1 57.02362 215.0236 cm +1 0 0 1 57.02362 179.0236 cm Q q -1 0 0 1 57.02362 173.0236 cm +1 0 0 1 57.02362 137.0236 cm q BT 1 0 0 1 0 26 Tm .35131 Tw 12 TL /F3 10 Tf 0 0 0 rg (Multi-shot continuations) Tj /F1 10 Tf (: Because the state is deep-copied at capture time, a continuation can be invoked) Tj T* 0 Tw .07131 Tw (multiple times. Each invocation restores an independent copy of the machine state. This enables generators,) Tj T* 0 Tw (coroutines, & backtracking search.) Tj T* ET Q Q q -1 0 0 1 57.02362 147.0236 cm +1 0 0 1 57.02362 111.0236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (4.1 Generators from Continuations) Tj T* ET Q Q q -1 0 0 1 57.02362 129.0236 cm +1 0 0 1 57.02362 93.02362 cm q BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (A generator in Lumbda uses ) Tj /F5 10 Tf (call/cc) Tj /F1 10 Tf ( to yield values & resume later:) Tj T* ET Q Q -q -1 0 0 1 57.02362 69.42362 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .960784 rg -n -6 -6 480.0283 50.4 re B* -Q -q -BT 1 0 0 1 0 30.4 Tm 9.6 TL /F5 8 Tf 0 0 0 rg (\(auto-compile! #t\)) Tj T* (\(define \(make-gen thunk\)) Tj T* ( \(let \(\(k #f\) \(done #f\)\)) Tj T* ( \(lambda \(\)) Tj T* ET -Q -Q -Q -Q -Q endstream endobj 120 0 obj << -/Length 9062 +/Length 9194 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 57.02362 627.0236 cm +1 0 0 1 57.02362 588.6236 cm q q 1 0 0 1 0 0 cm @@ -2072,42 +2071,42 @@ q .662745 .662745 .662745 RG .5 w .960784 .960784 .960784 rg -n -6 -6 480.0283 136.8 re B* +n -6 -6 480.0283 175.2 re B* Q q -BT 1 0 0 1 0 116.8 Tm 9.6 TL /F5 8 Tf 0 0 0 rg ( \(if done 'done) Tj T* ( \(call/cc \(lambda \(return\)) Tj T* ( \(if k \(k return\)) Tj T* ( \(begin \(thunk \(lambda \(val\)) Tj T* ( \(call/cc \(lambda \(next\)) Tj T* ( \(set! k next\) \(return val\)\)\)\)\)) Tj T* ( \(set! done #t\) \(return 'done\)\)\)\)\)\)\)\)\)) Tj T* T* (\(define counter \(make-gen \(lambda \(yield\)) Tj T* ( \(let loop \(\(i 0\)\) \(yield i\) \(loop \(+ i 1\)\)\)\)\)\)) Tj T* (\(counter\) ; =) Tj (>) Tj ( 0) Tj T* (\(counter\) ; =) Tj (>) Tj ( 1) Tj T* (\(counter\) ; =) Tj (>) Tj ( 2) Tj T* ET +BT 1 0 0 1 0 155.2 Tm 9.6 TL /F5 8 Tf 0 0 0 rg (\(auto-compile! #t\)) Tj T* (\(define \(make-gen thunk\)) Tj T* ( \(let \(\(k #f\) \(done #f\)\)) Tj T* ( \(lambda \(\)) Tj T* ( \(if done 'done) Tj T* ( \(call/cc \(lambda \(return\)) Tj T* ( \(if k \(k return\)) Tj T* ( \(begin \(thunk \(lambda \(val\)) Tj T* ( \(call/cc \(lambda \(next\)) Tj T* ( \(set! k next\) \(return val\)\)\)\)\)) Tj T* ( \(set! done #t\) \(return 'done\)\)\)\)\)\)\)\)\)) Tj T* T* (\(define counter \(make-gen \(lambda \(yield\)) Tj T* ( \(let loop \(\(i 0\)\) \(yield i\) \(loop \(+ i 1\)\)\)\)\)\)) Tj T* (\(counter\) ; =) Tj (>) Tj ( 0) Tj T* (\(counter\) ; =) Tj (>) Tj ( 1) Tj T* (\(counter\) ; =) Tj (>) Tj ( 2) Tj T* ET Q Q Q Q Q q -1 0 0 1 57.02362 595.0236 cm +1 0 0 1 57.02362 556.6236 cm q BT 1 0 0 1 0 14 Tm 4.875696 Tw 12 TL /F1 10 Tf 0 0 0 rg (No special generator syntax. No coroutine framework. The same ) Tj /F5 10 Tf (call/cc) Tj /F1 10 Tf ( that handles escape) Tj T* 0 Tw (continuations also handles cooperative multitasking, because feedback is feedback.) Tj T* ET Q Q q -1 0 0 1 57.02362 569.0236 cm +1 0 0 1 57.02362 530.6236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (4.2 Why "Feedback Is All You Need") Tj T* ET Q Q q -1 0 0 1 57.02362 551.0236 cm +1 0 0 1 57.02362 512.6236 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Every control flow pattern reduces to a continuation operation:) Tj T* ET Q Q q -1 0 0 1 57.02362 545.0236 cm +1 0 0 1 57.02362 506.6236 cm Q q -1 0 0 1 57.02362 545.0236 cm +1 0 0 1 57.02362 506.6236 cm Q q -1 0 0 1 57.02362 533.0236 cm +1 0 0 1 57.02362 494.6236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -2129,10 +2128,10 @@ Q Q Q q -1 0 0 1 57.02362 527.0236 cm +1 0 0 1 57.02362 488.6236 cm Q q -1 0 0 1 57.02362 515.0236 cm +1 0 0 1 57.02362 476.6236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -2154,10 +2153,10 @@ Q Q Q q -1 0 0 1 57.02362 509.0236 cm +1 0 0 1 57.02362 470.6236 cm Q q -1 0 0 1 57.02362 497.0236 cm +1 0 0 1 57.02362 458.6236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -2179,10 +2178,10 @@ Q Q Q q -1 0 0 1 57.02362 491.0236 cm +1 0 0 1 57.02362 452.6236 cm Q q -1 0 0 1 57.02362 479.0236 cm +1 0 0 1 57.02362 440.6236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -2204,10 +2203,10 @@ Q Q Q q -1 0 0 1 57.02362 473.0236 cm +1 0 0 1 57.02362 434.6236 cm Q q -1 0 0 1 57.02362 461.0236 cm +1 0 0 1 57.02362 422.6236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -2229,10 +2228,10 @@ Q Q Q q -1 0 0 1 57.02362 455.0236 cm +1 0 0 1 57.02362 416.6236 cm Q q -1 0 0 1 57.02362 431.0236 cm +1 0 0 1 57.02362 392.6236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -2254,10 +2253,10 @@ Q Q Q q -1 0 0 1 57.02362 425.0236 cm +1 0 0 1 57.02362 386.6236 cm Q q -1 0 0 1 57.02362 413.0236 cm +1 0 0 1 57.02362 374.6236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -2279,33 +2278,33 @@ Q Q Q q -1 0 0 1 57.02362 395.0236 cm +1 0 0 1 57.02362 356.6236 cm Q q -1 0 0 1 57.02362 377.0236 cm +1 0 0 1 57.02362 338.6236 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (One primitive. Every pattern.) Tj T* ET Q Q q -1 0 0 1 57.02362 351.0236 cm +1 0 0 1 57.02362 312.6236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (4.3 Four Scopes of Feedback) Tj T* ET Q Q q -1 0 0 1 57.02362 333.0236 cm +1 0 0 1 57.02362 294.6236 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The single word "feedback" covers four nested scopes, each giving rise to one of our core abstractions:) Tj T* ET Q Q q -1 0 0 1 57.02362 327.0236 cm +1 0 0 1 57.02362 288.6236 cm Q q -1 0 0 1 57.02362 237.0236 cm +1 0 0 1 57.02362 198.6236 cm q 1 1 1 rg n 0 90 481.2283 -18 re f* @@ -2480,16 +2479,16 @@ Q Q Q q -1 0 0 1 57.02362 237.0236 cm +1 0 0 1 57.02362 198.6236 cm Q q -1 0 0 1 57.02362 159.0236 cm +1 0 0 1 57.02362 120.6236 cm q BT 1 0 0 1 0 62 Tm .519908 Tw 12 TL /F1 10 Tf 0 0 0 rg (Within a single VM, a continuation is the unit \227 the whole call stack, captured & passed. Across processes) Tj T* 0 Tw 1.828917 Tw (on the same machine, a portal is the unit \227 the whole heap or VM state, serialized to a file, resumed) Tj T* 0 Tw 2.175257 Tw (elsewhere. Across implementations that share no binary compatibility, Scheme source itself is the unit:) Tj T* 0 Tw 1.27989 Tw /F5 10 Tf (\(define) Tj ( ) Tj (x) Tj ( ) Tj (42\)) Tj /F1 10 Tf ( travels because every parser already knows how to receive it. Across machines, bytes) Tj T* 0 Tw -0.111031 Tw (over a socket are the unit \227 an HTTP request is feedback to a peer, a response is feedback back. The HTTP) Tj T* 0 Tw (handler is 70 lines of portable Scheme that runs byte-identical in all three runtimes.) Tj T* ET Q Q q -1 0 0 1 57.02362 117.0236 cm +1 0 0 1 57.02362 78.62362 cm q BT 1 0 0 1 0 26 Tm .158138 Tw 12 TL /F1 10 Tf 0 0 0 rg (The same abstraction, at four scopes. No new primitive at any level \227 each scope adds one implementation) Tj T* 0 Tw 1.356019 Tw (primitive \() Tj /F5 10 Tf (call/cc) Tj /F1 10 Tf ( / portal / reader / socket\) and keeps the semantics. This is what "feedback is all you) Tj T* 0 Tw (need" actually means once you extend it past the process boundary.) Tj T* ET Q @@ -5804,7 +5803,7 @@ endstream endobj 129 0 obj << -/Length 3552 +/Length 4347 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET @@ -5957,7 +5956,7 @@ Q q 1 0 0 1 57.02362 541.8236 cm q -BT 1 0 0 1 0 2.2 Tm 13.2 TL /F2 11 Tf .133333 .133333 .133333 rg (11. Three Implementations, One Language) Tj T* ET +BT 1 0 0 1 0 2.2 Tm 13.2 TL /F2 11 Tf .133333 .133333 .133333 rg (11. Four Implementation Tiers, One Language) Tj T* ET Q Q q @@ -5983,7 +5982,13 @@ q 1 0 0 1 57.02362 515.8236 cm Q q -1 0 0 1 57.02362 507.8236 cm +1 0 0 1 57.02362 437.8236 cm +q +BT 1 0 0 1 0 62 Tm .778726 Tw 12 TL /F1 10 Tf 0 0 0 rg (Lumbda ships as four independently built tiers: a Python bytecode VM, a C tree-walker, a C bytecode VM,) Tj T* 0 Tw 2.18402 Tw (and a C x86_64 JIT \(the last three packaged in one binary, selectable by flag\), plus a pure-assembly) Tj T* 0 Tw .931492 Tw (interpreter. Each tier is MOAD-isolated from the others \227 a defect surfaced in one is fixed in that tier, not) Tj T* 0 Tw 2.098556 Tw (patched across shared infrastructure. All four run the same ) Tj /F5 10 Tf (.lsp) Tj /F1 10 Tf ( source files and exchange the same) Tj T* 0 Tw 2.266213 Tw (S-expression portal format; \24711.3-\24711.5 demonstrate this end-to-end across sockets, relays, and HTTP) Tj T* 0 Tw (portal transfers.) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 429.8236 cm Q endstream @@ -9256,79 +9261,79 @@ xref 0002151949 00000 n 0002152084 00000 n 0002152235 00000 n -0002152430 00000 n -0002152551 00000 n -0002152688 00000 n -0002152851 00000 n -0002153023 00000 n -0002153195 00000 n -0002153341 00000 n -0002153535 00000 n -0002153694 00000 n -0002153862 00000 n -0002153997 00000 n -0002154130 00000 n -0002154275 00000 n -0002154401 00000 n -0002154529 00000 n -0002154640 00000 n -0002154884 00000 n -0002159751 00000 n -0002166489 00000 n -0002171819 00000 n -0002178768 00000 n -0002187289 00000 n -0002196404 00000 n -0002205590 00000 n -0002218511 00000 n -0002228040 00000 n -0002238177 00000 n -0002246568 00000 n -0002256181 00000 n -0002264601 00000 n -0002273825 00000 n -0002277430 00000 n -0002279265 00000 n -0002292324 00000 n -0002309371 00000 n -0002319257 00000 n -0002326697 00000 n -0002333295 00000 n -0002341283 00000 n -0002349219 00000 n -0002355687 00000 n -0002357843 00000 n -0002358921 00000 n -0002359245 00000 n -0002359280 00000 n -0002359315 00000 n -0002359350 00000 n -0002359385 00000 n -0002359420 00000 n -0002359455 00000 n -0002359490 00000 n -0002359525 00000 n -0002359560 00000 n -0002359596 00000 n -0002359632 00000 n -0002359668 00000 n -0002359704 00000 n -0002359740 00000 n -0002359776 00000 n -0002359812 00000 n -0002359848 00000 n -0002359884 00000 n -0002359920 00000 n -0002359956 00000 n -0002359992 00000 n -0002360028 00000 n -0002360064 00000 n -0002360100 00000 n -0002360136 00000 n +0002152434 00000 n +0002152555 00000 n +0002152692 00000 n +0002152855 00000 n +0002153027 00000 n +0002153199 00000 n +0002153345 00000 n +0002153539 00000 n +0002153698 00000 n +0002153866 00000 n +0002154001 00000 n +0002154134 00000 n +0002154279 00000 n +0002154405 00000 n +0002154533 00000 n +0002154644 00000 n +0002154888 00000 n +0002159687 00000 n +0002167618 00000 n +0002172411 00000 n +0002179340 00000 n +0002188254 00000 n +0002197501 00000 n +0002206687 00000 n +0002219608 00000 n +0002229137 00000 n +0002239274 00000 n +0002247665 00000 n +0002257278 00000 n +0002265698 00000 n +0002274922 00000 n +0002279322 00000 n +0002281157 00000 n +0002294216 00000 n +0002311263 00000 n +0002321149 00000 n +0002328589 00000 n +0002335187 00000 n +0002343175 00000 n +0002351111 00000 n +0002357579 00000 n +0002359735 00000 n +0002360813 00000 n +0002361137 00000 n +0002361172 00000 n +0002361207 00000 n +0002361242 00000 n +0002361277 00000 n +0002361312 00000 n +0002361347 00000 n +0002361382 00000 n +0002361417 00000 n +0002361452 00000 n +0002361488 00000 n +0002361524 00000 n +0002361560 00000 n +0002361596 00000 n +0002361632 00000 n +0002361668 00000 n +0002361704 00000 n +0002361740 00000 n +0002361776 00000 n +0002361812 00000 n +0002361848 00000 n +0002361884 00000 n +0002361920 00000 n +0002361956 00000 n +0002361992 00000 n +0002362028 00000 n trailer << /ID -[] +[] % ReportLab generated PDF document -- digest (opensource) /Info 59 0 R @@ -9336,5 +9341,5 @@ trailer /Size 168 >> startxref -2360172 +2362064 %%EOF diff --git a/whitepaper/uncommonlisp-whitepaper.rst b/whitepaper/uncommonlisp-whitepaper.rst index b017275..76a7b0e 100644 --- a/whitepaper/uncommonlisp-whitepaper.rst +++ b/whitepaper/uncommonlisp-whitepaper.rst @@ -29,7 +29,7 @@ Lumbda .. class:: center -**A just-in-time lambda language — fast from first principles, workloads migratable across basic UNIX systems.** +**A Lisp/Scheme-derived, just-in-time lambda language. Four implementation tiers with EML mathematical universality and MOAD defect isolation. Workloads migrate across basic UNIX systems.** .. class:: center @@ -56,12 +56,13 @@ Abstract **License: AGPL-3.0-only** · This implementation, its bytecode VM, & all associated code carry the GNU Affero General Public License v3.0 (only). You may use, modify, & distribute under those terms. No proprietary relicensing exists. -A programming language needs one primitive to become universal: feedback. A function that receives its own continuation can loop, branch, yield, checkpoint, resume, & migrate. Every control flow pattern reduces to a continuation captured & invoked. Extend feedback across time (portals) & across implementations (source-as-wire-format) and you recover the full scope of computation without new primitives. +**Lumbda** is a Lisp/Scheme-derived language designed around two invariants that most languages discover late or never: **EML mathematical universality** (every elementary function expressible from a single operator, machine-checked in Lean 4 — see §8) and **MOAD defect isolation** (every implementation audited against the five canonical Mother-of-all-Defects patterns, with every defect confined to its own implementation tier rather than propagating through shared infrastructure — see §12). The rest of the design follows: one primitive, feedback, becomes universal when a function receives its own continuation. A continuation lets a program loop, branch, yield, checkpoint, resume, & migrate. Every control flow pattern reduces to a continuation captured & invoked. Extend feedback across time (portals) & across implementations (source-as-wire-format) and you recover the full scope of computation without new primitives. -**Lumbda** proves this by implementing R7RS Scheme three ways: +Lumbda ships in **four implementation tiers** — each independently built, each MOAD-isolated, each able to run every test in the shared functional suite byte-identically: - **Python bytecode VM** — 3,743 lines, full first-class continuations, JSON portal, reference implementation -- **C interpreter + x86_64 JIT** — 9,164 lines of runtime C (plus ~1,200 in the test harness), 7--10× faster than CPython on recursive workloads, JSON portal +- **C interpreter** — tree-walker + bytecode VM, 9,164 lines of runtime C, JSON portal +- **C + x86_64 JIT** — pattern-matched native code emission via ``mmap(PROT_EXEC)``, 7--10× faster than CPython on recursive workloads - **Pure x86_64 assembly** — 4,968 lines, 22 KB stripped binary, zero external dependencies, **91 builtins including a full TCP stack, `eval`, and `read-from-string`**, binary heap-dump portal All three share one interchange format: **Scheme source itself**. An S-expression portal (``(define x 42)``) written by any implementation loads in any other — a 3×3 producer×consumer matrix, 9/9 cells green. The language *is* the wire protocol. This is not a property we added; it is what a parser has always made possible. We report it because most systems forget. @@ -746,11 +747,13 @@ Lumbda forms one piece of a larger permacomputer machine learning stack: Lumbda provides the runtime layer: a language that can checkpoint its own execution, migrate between machines, & resume from serialized state. The portal system enables distributed computation across permacomputer nodes. Categorization & feedback activities could run inside Lumbda's VM, with ``call/cc`` providing the state machine transitions & portal providing persistence. -11. Three Implementations, One Language ---------------------------------------- +11. Four Implementation Tiers, One Language +-------------------------------------------- *"A diagram is worth 10,000 words."* — russell@unturf.com +Lumbda ships as four independently built tiers: a Python bytecode VM, a C tree-walker, a C bytecode VM, and a C x86_64 JIT (the last three packaged in one binary, selectable by flag), plus a pure-assembly interpreter. Each tier is MOAD-isolated from the others — a defect surfaced in one is fixed in that tier, not patched across shared infrastructure. All four run the same ``.lsp`` source files and exchange the same S-expression portal format; §11.3-§11.5 demonstrate this end-to-end across sockets, relays, and HTTP portal transfers. + .. figure:: diagrams/c-architecture.png :width: 80% :align: center