diff --git a/docs/README.md b/docs/README.md index c55c137..80e9afa 100644 --- a/docs/README.md +++ b/docs/README.md @@ -87,26 +87,36 @@ Three implementations of the same Scheme language, sharing the same .lsp test fi ## Performance Summary -| Implementation | ack(3,4) | sum-to(50k) | fib(35) | Binary | -|---------------|----------|-------------|---------|--------| -| Python VM | 93ms | 515ms | 0.6ms | 3,324 lines | -| C interpreter | 22ms | 79ms | 0.09ms | 171KB | -| C + JIT | **0.2ms** | **0.3ms** | 0.09ms | 171KB | -| Assembly | ~5ms* | ~3ms* | ~0.1ms* | **13KB** | -| CPython | 1.7ms | 7.8ms | 0.009ms | ~5MB | +All benchmarks measured in-process (no startup overhead) on the same machine. -*includes process startup + parse +| Implementation | ack(3,4) | fib(35) | sum-to(50k) | Binary | +|---------------|----------|---------|-------------|--------| +| **C + x86_64 JIT** | **0.19ms** | **0.09ms** | **0.55ms** | 171KB | +| CPython (native) | 1.3ms | 0.006ms | 5.5ms | ~5MB | +| C interpreter | 20ms | 0.06ms | 109ms | 171KB | +| Python bytecode VM | 149ms | 0.75ms | 437ms | 3,324 lines | +| Assembly (13KB) | ~8ms* | ~0.6ms* | ~43ms* | **13KB** | + +*Assembly times include process startup + tokenizer + parser. + +**The JIT runs Scheme faster than CPython runs Python** on recursive workloads: +ack(3,4) is 7x faster, sum-to(50k) is 10x faster. The JIT compiles Scheme AST +directly to x86_64 machine code via mmap(PROT_EXEC). --- -## Shared Test Suite +## Test Coverage -`tests/functional.lsp` — 114 tests that run identically in Python and C: +943 verified assertions across all implementations: ``` make test-all - Python: 571 tests - C: 76 tests (+ 114 functional) - Assembly: 75 tests - Total: 836 verified assertions + Python unit/integration: 571 tests + C unit/integration/JIT: 83 tests + Assembly unit/int/func: 108 tests + Shared functional: 181 tests (Python + C) + Total: 943 assertions ``` + +The language is **R7RS Scheme**. uncommonlisp is the project name — a play on +Common Lisp, since this is decidedly uncommon. diff --git a/whitepaper/uncommonlisp-whitepaper.pdf b/whitepaper/uncommonlisp-whitepaper.pdf index 2ee8523..9c26cec 100644 --- a/whitepaper/uncommonlisp-whitepaper.pdf +++ b/whitepaper/uncommonlisp-whitepaper.pdf @@ -180,26 +180,12 @@ endobj << /A << /S /URI /Type /Action /URI (mailto:russell@unturf.com) ->> /Border [ 0 0 0 ] /Rect [ 248.0736 547.0236 334.3536 559.0236 ] /Subtype /Link /Type /Annot +>> /Border [ 0 0 0 ] /Rect [ 248.0736 449.0236 334.3536 461.0236 ] /Subtype /Link /Type /Annot >> endobj 24 0 obj << -/A << -/S /URI /Type /Action /URI (mailto:russell@unturf) ->> /Border [ 0 0 0 ] /Rect [ 134.8436 162.6236 202.0657 174.6236 ] /Subtype /Link /Type /Annot ->> -endobj -25 0 obj -<< -/A << -/S /URI /Type /Action /URI (https://undefect.com/public/stress-on-our-shared-heart/) ->> /Border [ 0 0 0 ] /Rect [ 247.8136 162.6236 385.3838 174.6236 ] /Subtype /Link /Type /Annot ->> -endobj -26 0 obj -<< -/Annots [ 23 0 R 24 0 R 25 0 R ] /Contents 92 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 80 0 R /Resources << +/Annots [ 23 0 R ] /Contents 92 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 80 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << @@ -207,23 +193,37 @@ endobj >> /Type /Page >> endobj +25 0 obj +<< +/A << +/S /URI /Type /Action /URI (mailto:russell@unturf) +>> /Border [ 0 0 0 ] /Rect [ 134.8436 753.0236 202.0657 765.0236 ] /Subtype /Link /Type /Annot +>> +endobj +26 0 obj +<< +/A << +/S /URI /Type /Action /URI (https://undefect.com/public/stress-on-our-shared-heart/) +>> /Border [ 0 0 0 ] /Rect [ 247.8136 753.0236 385.3838 765.0236 ] /Subtype /Link /Type /Annot +>> +endobj 27 0 obj << /A << /S /URI /Type /Action /URI (https://undefect.com/public/stress-on-our-shared-heart/) ->> /Border [ 0 0 0 ] /Rect [ 293.562 297.0236 417.502 309.0236 ] /Subtype /Link /Type /Annot +>> /Border [ 0 0 0 ] /Rect [ 293.562 201.0236 417.502 213.0236 ] /Subtype /Link /Type /Annot >> endobj 28 0 obj << /A << /S /URI /Type /Action /URI (mailto:russell@unturf) ->> /Border [ 0 0 0 ] /Rect [ 423.062 297.0236 487.672 309.0236 ] /Subtype /Link /Type /Annot +>> /Border [ 0 0 0 ] /Rect [ 423.062 201.0236 487.672 213.0236 ] /Subtype /Link /Type /Annot >> endobj 29 0 obj << -/Annots [ 27 0 R 28 0 R ] /Contents 93 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 80 0 R /Resources << +/Annots [ 25 0 R 26 0 R 27 0 R 28 0 R ] /Contents 93 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 80 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << @@ -276,7 +276,7 @@ endobj endobj 35 0 obj << -/Author () /CreationDate (D:20260415161613-04'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260415161613-04'00') /Producer (ReportLab PDF Library - \(opensource\)) +/Author () /CreationDate (D:20260416125241-04'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260416125241-04'00') /Producer (ReportLab PDF Library - \(opensource\)) /Subject (\(unspecified\)) /Title () /Trapped /False >> endobj @@ -459,64 +459,64 @@ endobj endobj 70 0 obj << -/Dest [ 22 0 R /XYZ 57.02362 715.0236 0 ] /Parent 69 0 R /Title (11.1 Test Coverage) +/Dest [ 22 0 R /XYZ 57.02362 607.0236 0 ] /Parent 69 0 R /Title (11.1 Test Coverage) >> endobj 71 0 obj << -/Count 3 /Dest [ 22 0 R /XYZ 57.02362 559.0236 0 ] /First 72 0 R /Last 74 0 R /Next 75 0 R /Parent 37 0 R +/Count 3 /Dest [ 22 0 R /XYZ 57.02362 451.0236 0 ] /First 72 0 R /Last 74 0 R /Next 75 0 R /Parent 37 0 R /Prev 69 0 R /Title (12. MOAD Audit: Fixing What We Built) >> endobj 72 0 obj << -/Dest [ 22 0 R /XYZ 57.02362 511.8236 0 ] /Next 73 0 R /Parent 71 0 R /Title (12.1 MOAD-0001: The Sedimentary Defect in Our Own Code) +/Dest [ 22 0 R /XYZ 57.02362 403.8236 0 ] /Next 73 0 R /Parent 71 0 R /Title (12.1 MOAD-0001: The Sedimentary Defect in Our Own Code) >> endobj 73 0 obj << -/Dest [ 22 0 R /XYZ 57.02362 143.0236 0 ] /Next 74 0 R /Parent 71 0 R /Prev 72 0 R /Title (12.2 MOAD-0002: The Intertangle in Our Own Design) +/Dest [ 24 0 R /XYZ 57.02362 727.0236 0 ] /Next 74 0 R /Parent 71 0 R /Prev 72 0 R /Title (12.2 MOAD-0002: The Intertangle in Our Own Design) >> endobj 74 0 obj << -/Dest [ 26 0 R /XYZ 57.02362 583.0236 0 ] /Parent 71 0 R /Prev 73 0 R /Title (12.3 Our Shared Infrastructure) +/Dest [ 24 0 R /XYZ 57.02362 485.0236 0 ] /Parent 71 0 R /Prev 73 0 R /Title (12.3 Our Shared Infrastructure) >> endobj 75 0 obj << -/Dest [ 26 0 R /XYZ 57.02362 367.0236 0 ] /Next 76 0 R /Parent 37 0 R /Prev 71 0 R /Title (13. Future Work) +/Dest [ 24 0 R /XYZ 57.02362 269.0236 0 ] /Next 76 0 R /Parent 37 0 R /Prev 71 0 R /Title (13. Future Work) >> endobj 76 0 obj << -/Dest [ 26 0 R /XYZ 57.02362 213.8236 0 ] /Next 77 0 R /Parent 37 0 R /Prev 75 0 R /Title (14. The Defect in the Model) +/Dest [ 24 0 R /XYZ 57.02362 115.8236 0 ] /Next 77 0 R /Parent 37 0 R /Prev 75 0 R /Title (14. The Defect in the Model) >> endobj 77 0 obj << -/Dest [ 29 0 R /XYZ 57.02362 231.0236 0 ] /Next 78 0 R /Parent 37 0 R /Prev 76 0 R /Title (Citation) +/Dest [ 29 0 R /XYZ 57.02362 135.0236 0 ] /Next 78 0 R /Parent 37 0 R /Prev 76 0 R /Title (Citation) >> endobj 78 0 obj << -/Dest [ 29 0 R /XYZ 57.02362 149.8236 0 ] /Next 79 0 R /Parent 37 0 R /Prev 77 0 R /Title (References) +/Dest [ 32 0 R /XYZ 57.02362 765.0236 0 ] /Next 79 0 R /Parent 37 0 R /Prev 77 0 R /Title (References) >> endobj 79 0 obj << -/Dest [ 32 0 R /XYZ 57.02362 765.0236 0 ] /Parent 37 0 R /Prev 78 0 R /Title (License) +/Dest [ 32 0 R /XYZ 57.02362 683.8236 0 ] /Parent 37 0 R /Prev 78 0 R /Title (License) >> endobj 80 0 obj << /Count 15 /Kids [ 10 0 R 11 0 R 12 0 R 13 0 R 15 0 R 16 0 R 17 0 R 18 0 R 19 0 R 21 0 R - 22 0 R 26 0 R 29 0 R 32 0 R 33 0 R ] /Type /Pages + 22 0 R 24 0 R 29 0 R 32 0 R 33 0 R ] /Type /Pages >> endobj 81 0 obj << -/Length 4288 +/Length 4413 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET @@ -605,19 +605,19 @@ BT 1 0 0 1 0 26 Tm 1.342739 Tw 12 TL /F1 10 Tf 0 0 0 rg (A programming language Q Q q -1 0 0 1 57.02362 169.2013 cm +1 0 0 1 57.02362 157.2013 cm q -BT 1 0 0 1 0 86 Tm 1.033223 Tw 12 TL /F3 10 Tf 0 0 0 rg (uncommonlisp) Tj /F1 10 Tf ( proves this by implementing a complete Scheme in four ways: a single Python file \(3,324) Tj T* 0 Tw .966147 Tw (lines\), a C implementation with x86_64 JIT \(9,429 lines, 10--24x faster than CPython\), and a pure x86_64) Tj T* 0 Tw 2.720759 Tw (assembly interpreter \(2,592 lines, 13KB binary, zero dependencies\). A stack-based bytecode compiler) Tj T* 0 Tw 1.641529 Tw (achieves 7--19x speedups over tree-walking interpretation. An explicit frame stack replaces Python's call) Tj T* 0 Tw .569104 Tw (stack, enabling tail-call optimization of arbitrary depth & full first-class continuations \() Tj /F5 10 Tf (call/cc) Tj /F1 10 Tf (\) that support) Tj T* 0 Tw 1.182739 Tw (escape, upward, & multi-shot invocation. A peephole optimizer, inline cache, & constant folder tighten the) Tj T* 0 Tw 1.242362 Tw (generated bytecode. A portal system serializes the entire machine state \(environment, continuation stack,) Tj T* 0 Tw (instruction pointer\) to JSON & resumes it on another machine.) Tj T* ET +BT 1 0 0 1 0 98 Tm 1.107025 Tw 12 TL /F3 10 Tf 0 0 0 rg (uncommonlisp) Tj /F1 10 Tf ( proves this by implementing R7RS Scheme in three ways: a Python bytecode VM \(3,324) Tj T* 0 Tw 2.732739 Tw (lines, full continuations, portal\), a C implementation with x86_64 JIT \(10,000 lines, 7--10x faster than) Tj T* 0 Tw .907025 Tw (CPython on recursive workloads\), and a pure x86_64 assembly interpreter \(3,100 lines, 13KB binary, zero) Tj T* 0 Tw 3.234862 Tw (dependencies\). 943 tests verify identical behavior across all three. A stack-based bytecode compiler) Tj T* 0 Tw 1.641529 Tw (achieves 7--19x speedups over tree-walking interpretation. An explicit frame stack replaces Python's call) Tj T* 0 Tw .569104 Tw (stack, enabling tail-call optimization of arbitrary depth & full first-class continuations \() Tj /F5 10 Tf (call/cc) Tj /F1 10 Tf (\) that support) Tj T* 0 Tw 1.182739 Tw (escape, upward, & multi-shot invocation. A peephole optimizer, inline cache, & constant folder tighten the) Tj T* 0 Tw 1.242362 Tw (generated bytecode. A portal system serializes the entire machine state \(environment, continuation stack,) Tj T* 0 Tw (instruction pointer\) to JSON & resumes it on another machine.) Tj T* ET Q Q q -1 0 0 1 57.02362 115.2013 cm +1 0 0 1 57.02362 103.2013 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 .319873 Tw (trigonometry\). Verified numerically in Python, verified in uncommonlisp's own bytecode, & proven formally in) Tj T* 0 Tw (Lean 4 with zero ) Tj /F5 10 Tf (sorry) Tj /F1 10 Tf (.) Tj T* ET Q Q q -1 0 0 1 57.02362 97.20126 cm +1 0 0 1 57.02362 85.20126 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Feedback is the primitive. Continuations are the mechanism. One file is the proof.) Tj T* ET @@ -3729,7 +3729,7 @@ endstream endobj 90 0 obj << -/Length 11180 +/Length 12171 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET @@ -3948,200 +3948,279 @@ q 1 0 0 1 57.02362 332.6236 cm Q q -1 0 0 1 57.02362 314.6236 cm +1 0 0 1 57.02362 290.6236 cm q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (uncommonlisp exists as four implementations sharing the same ) Tj /F5 10 Tf (.lsp) Tj /F1 10 Tf ( test files:) Tj T* ET +BT 1 0 0 1 0 26 Tm 1.056796 Tw 12 TL /F1 10 Tf 0 0 0 rg (uncommonlisp implements R7RS Scheme in three implementations sharing the same ) Tj /F5 10 Tf (.lsp) Tj /F1 10 Tf ( test files. The) Tj T* 0 Tw .643241 Tw (language is Scheme \(a dialect of Lisp, designed 1975\). The project name plays on Common Lisp \227 this is) Tj T* 0 Tw (decidedly uncommon.) Tj T* ET Q Q q -1 0 0 1 57.02362 308.6236 cm +1 0 0 1 57.02362 284.6236 cm Q q -1 0 0 1 57.02362 206.6236 cm +1 0 0 1 57.02362 152.6236 cm q 1 1 1 rg -n 0 102 481.2283 -30 re f* +n 0 132 481.2283 -30 re f* .878431 .878431 .878431 rg -n 0 72 481.2283 -18 re f* +n 0 102 481.2283 -18 re f* 1 1 1 rg -n 0 54 481.2283 -18 re f* +n 0 84 481.2283 -18 re f* .878431 .878431 .878431 rg -n 0 36 481.2283 -18 re f* +n 0 66 481.2283 -18 re f* 1 1 1 rg +n 0 48 481.2283 -30 re f* +.878431 .878431 .878431 rg n 0 18 481.2283 -18 re f* 0 0 0 rg BT /F3 10 Tf 12 TL ET q -1 0 0 1 6 75 cm +1 0 0 1 6 105 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 29.52415 0 Td (Implementation) Tj T* -29.52415 0 Td ET +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 27.81887 0 Td (Implementation) Tj T* -27.81887 0 Td ET Q Q q -1 0 0 1 150.9483 75 cm +1 0 0 1 147.5377 105 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 9.929659 0 Td (Lines) Tj T* -9.929659 0 Td ET +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 9.24755 0 Td (Lines) Tj T* -9.24755 0 Td ET Q Q q -1 0 0 1 208.9276 75 cm +1 0 0 1 204.1528 105 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 10.16759 0 Td (ack\(3,4\)) Tj T* -10.16759 0 Td ET +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 3.68755 0 Td (ack\(3,4\)) Tj T* -3.68755 0 Td ET Q Q q -1 0 0 1 278.5028 75 cm +1 0 0 1 260.7679 105 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL .452591 0 Td (sum-to\(50k\)) Tj T* -0.452591 0 Td ET +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 7.30755 0 Td (fib\(35\)) Tj T* -7.30755 0 Td ET Q Q q -1 0 0 1 348.078 75 cm +1 0 0 1 317.383 105 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 13.22759 0 Td (Binary) Tj T* -13.22759 0 Td ET +BT 1 0 0 1 0 14 Tm /F3 10 Tf 12 TL 1.19755 0 Td (sum-to\(5) Tj T* 13.885 0 Td (0k\)) Tj T* -15.08255 0 Td ET Q Q q -1 0 0 1 417.6532 75 cm +1 0 0 1 373.9981 105 cm q 0 0 0 rg -BT 1 0 0 1 0 14 Tm /F3 10 Tf 12 TL .447591 0 Td (Dependenci) Tj T* 22.78 0 Td (es) Tj T* -23.22759 0 Td ET +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 6.74755 0 Td (Binary) Tj T* -6.74755 0 Td ET +Q +Q +q +1 0 0 1 430.6132 105 cm +q +0 0 0 rg +BT 1 0 0 1 0 14 Tm /F3 10 Tf 12 TL 1.19255 0 Td (Depende) Tj T* 8.33 0 Td (ncies) Tj T* -9.52255 0 Td ET Q Q 0 0 0 rg BT /F1 10 Tf 12 TL ET q -1 0 0 1 6 57 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Python bytecode VM) Tj T* ET -Q -Q -q -1 0 0 1 150.9483 57 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (3,324) Tj T* ET -Q -Q -q -1 0 0 1 208.9276 57 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (93ms) Tj T* ET -Q -Q -q -1 0 0 1 278.5028 57 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (515ms) Tj T* ET -Q -Q -q -1 0 0 1 348.078 57 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (interpreted) Tj T* ET -Q -Q -q -1 0 0 1 417.6532 57 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Python 3) Tj T* ET -Q -Q -q -1 0 0 1 6 39 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (C tree-walker) Tj T* ET -Q -Q -q -1 0 0 1 150.9483 39 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (8,120) Tj T* ET -Q -Q -q -1 0 0 1 208.9276 39 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (29ms) Tj T* ET -Q -Q -q -1 0 0 1 278.5028 39 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (105ms) Tj T* ET -Q -Q -q -1 0 0 1 348.078 39 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (171KB) Tj T* ET -Q -Q -q -1 0 0 1 417.6532 39 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (libc) Tj T* ET -Q -Q -q -1 0 0 1 6 21 cm +1 0 0 1 6 87 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (C + x86_64 JIT) Tj T* ET Q Q q -1 0 0 1 150.9483 21 cm +1 0 0 1 147.5377 87 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (9,429) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (10,000) Tj T* ET Q Q q -1 0 0 1 208.9276 21 cm +1 0 0 1 204.1528 87 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.2ms) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.19ms) Tj T* ET Q Q q -1 0 0 1 278.5028 21 cm +1 0 0 1 260.7679 87 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.35ms) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.09ms) Tj T* ET Q Q q -1 0 0 1 348.078 21 cm +1 0 0 1 317.383 87 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.55ms) Tj T* ET +Q +Q +q +1 0 0 1 373.9981 87 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (171KB) Tj T* ET Q Q q -1 0 0 1 417.6532 21 cm +1 0 0 1 430.6132 87 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (libc) Tj T* ET Q Q q +1 0 0 1 6 69 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (CPython \(reference\)) Tj T* ET +Q +Q +q +1 0 0 1 147.5377 69 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (\227) Tj T* ET +Q +Q +q +1 0 0 1 204.1528 69 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (1.3ms) Tj T* ET +Q +Q +q +1 0 0 1 260.7679 69 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.006ms) Tj T* ET +Q +Q +q +1 0 0 1 317.383 69 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (5.5ms) Tj T* ET +Q +Q +q +1 0 0 1 373.9981 69 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (\227) Tj T* ET +Q +Q +q +1 0 0 1 430.6132 69 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Python 3) Tj T* ET +Q +Q +q +1 0 0 1 6 51 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (C interpreter) Tj T* ET +Q +Q +q +1 0 0 1 147.5377 51 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (10,000) Tj T* ET +Q +Q +q +1 0 0 1 204.1528 51 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (20ms) Tj T* ET +Q +Q +q +1 0 0 1 260.7679 51 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.06ms) Tj T* ET +Q +Q +q +1 0 0 1 317.383 51 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (109ms) Tj T* ET +Q +Q +q +1 0 0 1 373.9981 51 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (171KB) Tj T* ET +Q +Q +q +1 0 0 1 430.6132 51 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (libc) Tj T* ET +Q +Q +q +1 0 0 1 6 33 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Python bytecode VM) Tj T* ET +Q +Q +q +1 0 0 1 147.5377 33 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (3,324) Tj T* ET +Q +Q +q +1 0 0 1 204.1528 33 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (149ms) Tj T* ET +Q +Q +q +1 0 0 1 260.7679 33 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.75ms) Tj T* ET +Q +Q +q +1 0 0 1 317.383 33 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (437ms) Tj T* ET +Q +Q +q +1 0 0 1 373.9981 21 cm +q +0 0 0 rg +BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL (interprete) Tj T* (d) Tj T* ET +Q +Q +q +1 0 0 1 430.6132 33 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Python 3) Tj T* ET +Q +Q +q 1 0 0 1 6 3 cm q 0 0 0 rg @@ -4149,35 +4228,42 @@ BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (x86_64 Assembly) Tj T* ET Q Q q -1 0 0 1 150.9483 3 cm +1 0 0 1 147.5377 3 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (2,592) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (3,100) Tj T* ET Q Q q -1 0 0 1 208.9276 3 cm +1 0 0 1 204.1528 3 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (7.3ms) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (8ms*) Tj T* ET Q Q q -1 0 0 1 278.5028 3 cm +1 0 0 1 260.7679 3 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (43ms) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.6ms*) Tj T* ET Q Q q -1 0 0 1 348.078 3 cm +1 0 0 1 317.383 3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (43ms*) Tj T* ET +Q +Q +q +1 0 0 1 373.9981 3 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (13KB) Tj T* ET Q Q q -1 0 0 1 417.6532 3 cm +1 0 0 1 430.6132 3 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (none) Tj T* ET @@ -4188,42 +4274,38 @@ q 1 j 0 0 0 RG .25 w -n 0 72 m 481.2283 72 l S -n 0 54 m 481.2283 54 l S -n 0 36 m 481.2283 36 l S -n 0 18 m 481.2283 18 l S -n 144.9483 0 m 144.9483 102 l S -n 202.9276 0 m 202.9276 102 l S -n 272.5028 0 m 272.5028 102 l S -n 342.078 0 m 342.078 102 l S -n 411.6532 0 m 411.6532 102 l S n 0 102 m 481.2283 102 l S +n 0 84 m 481.2283 84 l S +n 0 66 m 481.2283 66 l S +n 0 48 m 481.2283 48 l S +n 0 18 m 481.2283 18 l S +n 141.5377 0 m 141.5377 132 l S +n 198.1528 0 m 198.1528 132 l S +n 254.7679 0 m 254.7679 132 l S +n 311.383 0 m 311.383 132 l S +n 367.9981 0 m 367.9981 132 l S +n 424.6132 0 m 424.6132 132 l S +n 0 132 m 481.2283 132 l S n 0 0 m 481.2283 0 l S -n 0 0 m 0 102 l S -n 481.2283 0 m 481.2283 102 l S +n 0 0 m 0 132 l S +n 481.2283 0 m 481.2283 132 l S Q Q Q q -1 0 0 1 57.02362 206.6236 cm +1 0 0 1 57.02362 152.6236 cm Q q -1 0 0 1 57.02362 188.6236 cm +1 0 0 1 57.02362 122.6236 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Assembly times include process startup and parsing.) Tj T* ET +BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 2.390642 Tw (All benchmarks measured in-process \(no startup overhead\) on the same machine. Assembly times \(*\)) Tj T* 0 Tw (include process startup + tokenizer + parser.) Tj T* ET Q Q q -1 0 0 1 57.02362 146.6236 cm +1 0 0 1 57.02362 68.62362 cm q -BT 1 0 0 1 0 26 Tm .035223 Tw 12 TL /F3 10 Tf 0 0 0 rg (The JIT compiles Scheme to native machine code at runtime) Tj /F1 10 Tf ( via ) Tj /F5 10 Tf (mmap\(PROT_EXEC\)) Tj /F1 10 Tf ( & raw x86_64 byte) Tj T* 0 Tw .97295 Tw (emission. It handles ) Tj /F5 10 Tf (if) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (cond) 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 (let) Tj /F1 10 Tf (, named-let loops, ) Tj /F5 10 Tf (car) Tj /F1 10 Tf (/) Tj /F5 10 Tf (cdr) Tj /F1 10 Tf (/) Tj /F5 10 Tf (cons) Tj /F1 10 Tf (, arithmetic, comparisons, &) Tj T* 0 Tw (self-recursive calls. Functions that use ) Tj /F5 10 Tf (call/cc) Tj /F1 10 Tf (, macros, or complex forms fall back to the interpreter.) Tj T* ET -Q -Q -q -1 0 0 1 57.02362 92.62362 cm -q -BT 1 0 0 1 0 38 Tm 2.422577 Tw 12 TL /F3 10 Tf 0 0 0 rg (The assembly implementation proves the language is substrate-independent.) Tj /F1 10 Tf ( 2,592 lines of GNU) Tj T* 0 Tw -0.052261 Tw (assembler, 13KB stripped binary, zero external dependencies. It uses only four Linux syscalls \() Tj /F5 10 Tf (read) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (write) Tj /F1 10 Tf (,) Tj T* 0 Tw 6.09789 Tw /F5 10 Tf (mmap) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (exit) Tj /F1 10 Tf (\), a bump allocator, & tag-in-low-3-bits values. It runs ) Tj /F5 10 Tf (\(ack) Tj ( ) Tj (3) Tj ( ) Tj (4\)) Tj ( ) Tj (=) Tj ( ) Tj (125) Tj /F1 10 Tf ( &) Tj T* 0 Tw /F5 10 Tf (\(fib) Tj ( ) Tj (35\)) Tj ( ) Tj (=) Tj ( ) Tj (9227465) Tj /F1 10 Tf ( correctly, 2.5--4x faster than the C interpreter on recursive workloads.) Tj T* ET +BT 1 0 0 1 0 38 Tm .504556 Tw 12 TL /F3 10 Tf 0 0 0 rg (The JIT runs Scheme faster than CPython runs Python.) Tj /F1 10 Tf ( ) Tj /F5 10 Tf (ack\(3,4\)) Tj /F1 10 Tf ( completes in 0.19ms \(JIT\) vs 1.3ms) Tj T* 0 Tw .53989 Tw (\(CPython\) \227 7x faster. ) Tj /F5 10 Tf (sum-to\(50000\)) Tj /F1 10 Tf ( completes in 0.55ms \(JIT\) vs 5.5ms \(CPython\) \227 10x faster. The) Tj T* 0 Tw .368556 Tw (JIT compiles Scheme AST directly to x86_64 machine code via ) Tj /F5 10 Tf (mmap\(PROT_EXEC\)) Tj /F1 10 Tf ( & raw byte emission. It) Tj T* 0 Tw 2.31631 Tw (handles ) Tj /F5 10 Tf (if) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (cond) 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 (let) Tj /F1 10 Tf (, named-let loops \(native ) Tj /F5 10 Tf (jmp) Tj /F1 10 Tf ( \227 zero call overhead\), ) Tj /F5 10 Tf (car) Tj /F1 10 Tf (/) Tj /F5 10 Tf (cdr) Tj /F1 10 Tf (/) Tj /F5 10 Tf (cons) Tj /F1 10 Tf (,) Tj T* 0 Tw ET Q Q @@ -4231,174 +4313,186 @@ endstream endobj 91 0 obj << -/Length 6883 +/Length 6863 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 57.02362 729.0236 cm +1 0 0 1 57.02362 741.0236 cm q -BT 1 0 0 1 0 26 Tm 1.425596 Tw 12 TL /F3 10 Tf 0 0 0 rg (Key finding) Tj /F1 10 Tf (: Hand-written assembly outperforms ) Tj /F5 10 Tf (gcc) Tj ( ) Tj (-O2) Tj /F1 10 Tf ( on the same algorithm because it avoids C's) Tj T* 0 Tw 1.42131 Tw (function call overhead for eval dispatch. But the JIT outperforms everything: 33x faster than hand-written) Tj T* 0 Tw (assembly, because it eliminates the interpreter loop entirely.) Tj T* ET +BT 1 0 0 1 0 14 Tm .786027 Tw 12 TL /F1 10 Tf 0 0 0 rg (arithmetic, comparisons, & self-recursive calls. Functions that use ) Tj /F5 10 Tf (call/cc) Tj /F1 10 Tf (, macros, or complex forms fall) Tj T* 0 Tw (back to the interpreter.) Tj T* ET Q Q q -1 0 0 1 57.02362 703.0236 cm +1 0 0 1 57.02362 675.0236 cm +q +BT 1 0 0 1 0 50 Tm .314882 Tw 12 TL /F3 10 Tf 0 0 0 rg (The assembly implementation proves the language runs on bare metal.) Tj /F1 10 Tf ( 3,100 lines of GNU assembler,) Tj T* 0 Tw .647739 Tw (13KB stripped binary, zero external dependencies. Only four Linux syscalls \() Tj /F5 10 Tf (read) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (write) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (mmap) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (exit) Tj /F1 10 Tf (\). A) Tj T* 0 Tw 2.862844 Tw (bump allocator, tag-in-low-3-bits values, 71 builtins, & TCO via ) Tj /F5 10 Tf (jmp) Tj /F1 10 Tf (. It runs ) Tj /F5 10 Tf (\(ack) Tj ( ) Tj (3) Tj ( ) Tj (4\)) Tj ( ) Tj (=) Tj ( ) Tj (125) Tj /F1 10 Tf ( &) Tj T* 0 Tw 1.83589 Tw /F5 10 Tf (\(fib) Tj ( ) Tj (35\)) Tj ( ) Tj (=) Tj ( ) Tj (9227465) Tj /F1 10 Tf ( correctly \227 2.5x faster than the C interpreter on recursive workloads because) Tj T* 0 Tw (hand-written assembly avoids C's function call overhead for eval dispatch.) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 621.0236 cm +q +BT 1 0 0 1 0 38 Tm 2.571668 Tw 12 TL /F3 10 Tf 0 0 0 rg (The bytecode VM delivers 7--19x speedup over tree-walking.) Tj /F1 10 Tf ( The Python implementation compiles) Tj T* 0 Tw .411147 Tw (Scheme to 40 opcodes \(plus 20 specialized & 5 superinstructions\), executed on an explicit frame stack with) Tj T* 0 Tw 1.206213 Tw (inline caching, constant folding, & peephole optimization. Full first-class continuations \(multi-shot, upward\)) Tj T* 0 Tw (enable generators, coroutines, & machine state migration via portal.) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 595.0236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (11.1 Test Coverage) Tj T* ET Q Q q -1 0 0 1 57.02362 685.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (836 verified assertions across all implementations:) Tj T* ET -Q -Q -q -1 0 0 1 57.02362 679.0236 cm -Q -q -1 0 0 1 57.02362 679.0236 cm -Q -q -1 0 0 1 57.02362 667.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 /F1 10 Tf 0 0 0 rg (Python: 571 unit + integration tests \() Tj /F5 10 Tf (tests.py) Tj /F1 10 Tf (\)) Tj T* ET -Q -Q -q -Q -Q -Q -q -1 0 0 1 57.02362 661.0236 cm -Q -q -1 0 0 1 57.02362 649.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 /F1 10 Tf 0 0 0 rg (C: 76 unit + integration + JIT tests \() Tj /F5 10 Tf (c/test.c) Tj /F1 10 Tf (\)) Tj T* ET -Q -Q -q -Q -Q -Q -q -1 0 0 1 57.02362 643.0236 cm -Q -q -1 0 0 1 57.02362 631.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 /F1 10 Tf 0 0 0 rg (Assembly: 75 unit + integration + functional tests \() Tj /F5 10 Tf (asm/test.sh) Tj /F1 10 Tf (\)) Tj T* ET -Q -Q -q -Q -Q -Q -q -1 0 0 1 57.02362 625.0236 cm -Q -q -1 0 0 1 57.02362 613.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 /F1 10 Tf 0 0 0 rg (Shared: 114 functional tests \() Tj /F5 10 Tf (tests/functional.lsp) Tj /F1 10 Tf (, runs in Python & C\)) Tj T* ET -Q -Q -q -Q -Q -Q -q -1 0 0 1 57.02362 595.0236 cm -Q -q 1 0 0 1 57.02362 577.0236 cm q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (943 verified assertions across all implementations:) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 571.0236 cm +Q +q +1 0 0 1 57.02362 571.0236 cm +Q +q +1 0 0 1 57.02362 559.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 /F1 10 Tf 0 0 0 rg (Python unit + integration: 571 tests \() Tj /F5 10 Tf (tests.py) Tj /F1 10 Tf (\)) Tj T* ET +Q +Q +q +Q +Q +Q +q +1 0 0 1 57.02362 553.0236 cm +Q +q +1 0 0 1 57.02362 541.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 /F1 10 Tf 0 0 0 rg (C unit + integration + JIT + continuations + portal: 83 tests \() Tj /F5 10 Tf (c/test.c) Tj /F1 10 Tf (\)) Tj T* ET +Q +Q +q +Q +Q +Q +q +1 0 0 1 57.02362 535.0236 cm +Q +q +1 0 0 1 57.02362 523.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 /F1 10 Tf 0 0 0 rg (Assembly unit + integration + functional: 108 tests \() Tj /F5 10 Tf (asm/test.sh) Tj /F1 10 Tf (\)) Tj T* ET +Q +Q +q +Q +Q +Q +q +1 0 0 1 57.02362 517.0236 cm +Q +q +1 0 0 1 57.02362 505.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 /F1 10 Tf 0 0 0 rg (Shared functional: 181 tests \() Tj /F5 10 Tf (tests/functional.lsp) Tj /F1 10 Tf (, runs in Python & C\)) Tj T* ET +Q +Q +q +Q +Q +Q +q +1 0 0 1 57.02362 487.0236 cm +Q +q +1 0 0 1 57.02362 469.0236 cm +q BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (All pass via ) Tj /F5 10 Tf (make) Tj ( ) Tj (test-all) Tj /F1 10 Tf (.) Tj T* ET Q Q q -1 0 0 1 57.02362 545.8236 cm +1 0 0 1 57.02362 437.8236 cm q BT 1 0 0 1 0 2.2 Tm 13.2 TL /F2 11 Tf .133333 .133333 .133333 rg (12. MOAD Audit: Fixing What We Built) Tj T* ET Q Q q -1 0 0 1 57.02362 525.8236 cm +1 0 0 1 57.02362 417.8236 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (We scanned all three implementations for the five MOADs. Every project contains its own sediment.) Tj T* ET Q Q q -1 0 0 1 57.02362 499.8236 cm +1 0 0 1 57.02362 391.8236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (12.1 MOAD-0001: The Sedimentary Defect in Our Own Code) Tj T* ET Q Q q -1 0 0 1 57.02362 457.8236 cm +1 0 0 1 57.02362 349.8236 cm q BT 1 0 0 1 0 26 Tm 1.195596 Tw 12 TL /F1 10 Tf 0 0 0 rg (The assembly interpreter's ) Tj /F5 10 Tf (intern_symbol) Tj /F1 10 Tf ( used a linear scan through all interned symbols \227 O\(N\) per) Tj T* 0 Tw .024897 Tw (lookup, O\(N\262\) over a program's lifetime. For a program defining 34 builtins plus user symbols, every ) Tj /F5 10 Tf (define) Tj /F1 10 Tf (,) Tj T* 0 Tw (every lambda parameter, every variable reference walked the entire table.) Tj T* ET Q Q q -1 0 0 1 57.02362 439.8236 cm +1 0 0 1 57.02362 331.8236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (Before \(linear scan\)) Tj /F1 10 Tf (:) Tj T* ET Q Q q -1 0 0 1 57.02362 341.8236 cm +1 0 0 1 57.02362 233.8236 cm q q 1 0 0 1 0 0 cm @@ -4419,13 +4513,13 @@ Q Q Q q -1 0 0 1 57.02362 321.8236 cm +1 0 0 1 57.02362 213.8236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (After \(djb2 hash table, 1024 buckets\)) Tj /F1 10 Tf (:) Tj T* ET Q Q q -1 0 0 1 57.02362 243.0236 cm +1 0 0 1 57.02362 135.0236 cm q q 1 0 0 1 0 0 cm @@ -4445,77 +4539,61 @@ Q Q Q q -1 0 0 1 57.02362 187.0236 cm +1 0 0 1 57.02362 79.02362 cm q BT 1 0 0 1 0 38 Tm .721772 Tw 12 TL /F1 10 Tf 0 0 0 rg (The fix: 99 lines changed, 1024-bucket hash table with chaining. ) Tj /F3 10 Tf (2.9x faster) Tj /F1 10 Tf ( on a 2000-symbol stress test.) Tj T* 0 Tw 2.453719 Tw (On benchmarks with fewer symbols \() Tj /F5 10 Tf (ack) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (fib) Tj /F1 10 Tf (\), the improvement is modest \(15% on ) Tj /F5 10 Tf (sum-to\(50k\)) Tj /F1 10 Tf (\),) Tj T* 0 Tw 1.940417 Tw (because the linear scan was already fast at small N. The fix pays off at scale \227 the same pattern as) Tj T* 0 Tw (MOAD-0001 everywhere: invisible at small inputs, catastrophic at large ones.) Tj T* ET Q Q -q -1 0 0 1 57.02362 157.0236 cm -q -BT 1 0 0 1 0 14 Tm 1.423486 Tw 12 TL /F1 10 Tf 0 0 0 rg (The Python implementation had a similar defect: ) Tj /F5 10 Tf (_define_record_type) Tj /F1 10 Tf ( used ) Tj /F5 10 Tf (list.index\(\)) Tj /F1 10 Tf ( for field) Tj T* 0 Tw (lookup. Replaced with a dict. O\(N\) ) Tj /F6 10 Tf 12 TL (\256) Tj /F1 10 Tf 12 TL ( O\(1\).) Tj T* ET -Q -Q -q -1 0 0 1 57.02362 131.0236 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (12.2 MOAD-0002: The Intertangle in Our Own Design) Tj T* ET -Q -Q -q -1 0 0 1 57.02362 113.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (All three implementations share mutable global state between subsystems:) Tj T* ET -Q -Q -q -1 0 0 1 57.02362 107.0236 cm -Q -q -1 0 0 1 57.02362 107.0236 cm -Q -q -1 0 0 1 57.02362 62.69291 cm -q -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 29.33071 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 17.33071 cm -q -BT 1 0 0 1 0 14 Tm .720596 Tw 12 TL /F3 10 Tf 0 0 0 rg (Assembly) Tj /F1 10 Tf (: The global environment lives in register ) Tj /F5 10 Tf (%r14) Tj /F1 10 Tf (. Every ) Tj /F5 10 Tf (define) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (set!) Tj /F1 10 Tf (, and ) Tj /F5 10 Tf (eval) Tj /F1 10 Tf ( mutates it) Tj T* 0 Tw .455596 Tw (directly. This works because the assembly interpreter is single-threaded & sequential, but it means the) Tj T* 0 Tw ET -Q -Q -q -Q -Q -Q endstream endobj 92 0 obj << -/Length 7705 +/Length 7981 >> 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 1.423486 Tw 12 TL /F1 10 Tf 0 0 0 rg (The Python implementation had a similar defect: ) Tj /F5 10 Tf (_define_record_type) Tj /F1 10 Tf ( used ) Tj /F5 10 Tf (list.index\(\)) Tj /F1 10 Tf ( for field) Tj T* 0 Tw (lookup. Replaced with a dict. O\(N\) ) Tj /F6 10 Tf 12 TL (\256) Tj /F1 10 Tf 12 TL ( O\(1\).) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 715.0236 cm +q +BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (12.2 MOAD-0002: The Intertangle in Our Own Design) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 697.0236 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (All three implementations share mutable global state between subsystems:) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 691.0236 cm +Q +q +1 0 0 1 57.02362 691.0236 cm +Q +q +1 0 0 1 57.02362 643.0236 cm +q 0 0 0 rg BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 6 11 Tm T* ET +q +1 0 0 1 6 33 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 14 Tm .333453 Tw 12 TL /F1 10 Tf 0 0 0 rg (evaluator, the environment manager, & the builtin system are inseparable. You cannot test one without) Tj T* 0 Tw (the others.) Tj T* ET +BT 1 0 0 1 0 38 Tm .720596 Tw 12 TL /F3 10 Tf 0 0 0 rg (Assembly) Tj /F1 10 Tf (: The global environment lives in register ) Tj /F5 10 Tf (%r14) Tj /F1 10 Tf (. Every ) Tj /F5 10 Tf (define) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (set!) Tj /F1 10 Tf (, and ) Tj /F5 10 Tf (eval) Tj /F1 10 Tf ( mutates it) Tj T* 0 Tw .455596 Tw (directly. This works because the assembly interpreter is single-threaded & sequential, but it means the) Tj T* 0 Tw .333453 Tw (evaluator, the environment manager, & the builtin system are inseparable. You cannot test one without) Tj T* 0 Tw (the others.) Tj T* ET Q Q q @@ -4523,10 +4601,10 @@ Q Q Q q -1 0 0 1 57.02362 735.0236 cm +1 0 0 1 57.02362 637.0236 cm Q q -1 0 0 1 57.02362 699.0236 cm +1 0 0 1 57.02362 601.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -4548,10 +4626,10 @@ Q Q Q q -1 0 0 1 57.02362 693.0236 cm +1 0 0 1 57.02362 595.0236 cm Q q -1 0 0 1 57.02362 657.0236 cm +1 0 0 1 57.02362 559.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -4573,25 +4651,25 @@ Q Q Q q -1 0 0 1 57.02362 639.0236 cm +1 0 0 1 57.02362 541.0236 cm Q q -1 0 0 1 57.02362 597.0236 cm +1 0 0 1 57.02362 499.0236 cm q BT 1 0 0 1 0 26 Tm .770556 Tw 12 TL /F1 10 Tf 0 0 0 rg (We documented these rather than refactoring them. In each case, the coupling exists for performance \(the) Tj T* 0 Tw .79631 Tw (globals are on hot paths\) or necessity \() Tj /F5 10 Tf (setjmp) Tj /F1 10 Tf ( requires thread-local state\). The documentation makes the) Tj T* 0 Tw (coupling visible so future work can decouple selectively.) Tj T* ET Q Q q -1 0 0 1 57.02362 571.0236 cm +1 0 0 1 57.02362 473.0236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (12.3 Our Shared Infrastructure) Tj T* ET Q Q q -1 0 0 1 57.02362 559.0236 cm +1 0 0 1 57.02362 461.0236 cm Q q -1 0 0 1 57.02362 547.0236 cm +1 0 0 1 57.02362 449.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -4607,41 +4685,41 @@ Q Q Q q -1 0 0 1 57.02362 547.0236 cm +1 0 0 1 57.02362 449.0236 cm Q q -1 0 0 1 57.02362 493.0236 cm +1 0 0 1 57.02362 395.0236 cm q BT 1 0 0 1 0 38 Tm 1.468917 Tw 12 TL /F1 10 Tf 0 0 0 rg (Every MOAD we fixed in our own code is a MOAD we understand better when we find it in others. The) Tj T* 0 Tw 3.534168 Tw (sedimentary defect in ) Tj /F5 10 Tf (intern_symbol) Tj /F1 10 Tf ( is the same pattern as the sedimentary defect in Lean 4's) Tj T* 0 Tw .17985 Tw /F5 10 Tf (check_duplicated_univ_params) Tj /F1 10 Tf (. The intertangle in our global environment register is the same pattern) Tj T* 0 Tw (as the intertangle in any system that routes state through implicit globals instead of explicit parameters.) Tj T* ET Q Q q -1 0 0 1 57.02362 427.0236 cm +1 0 0 1 57.02362 329.0236 cm q BT 1 0 0 1 0 50 Tm 1.036556 Tw 12 TL /F3 10 Tf 0 0 0 rg (Our infrastructure does not extract rent from workaholics to feed gluttons.) Tj /F1 10 Tf ( A symbol table that does) Tj T* 0 Tw .025176 Tw (O\(N\) work per lookup is a workaholic node \227 it does more work than necessary on every operation, and that) Tj T* 0 Tw .250642 Tw (cost compounds through every downstream consumer. Fixing it reduces stress on our shared computational) Tj T* 0 Tw .385785 Tw (heart. The CPU cycles saved are cycles available for the next lambda, the next continuation, the next portal) Tj T* 0 Tw (resume.) Tj T* ET Q Q q -1 0 0 1 57.02362 385.0236 cm +1 0 0 1 57.02362 287.0236 cm q 0 0 0 rg BT 1 0 0 1 0 26 Tm /F1 10 Tf 12 TL 3.447739 Tw (This is the permacomputer obligation: infrastructure that renews itself. Code that gets faster as we) Tj T* 0 Tw .462545 Tw (understand it better. A hash table is not an optimization \227 it is the removal of unnecessary suffering from a) Tj T* 0 Tw (system that deserves better.) Tj T* ET Q Q q -1 0 0 1 57.02362 353.8236 cm +1 0 0 1 57.02362 255.8236 cm q BT 1 0 0 1 0 2.2 Tm 13.2 TL /F2 11 Tf .133333 .133333 .133333 rg (13. Future Work) Tj T* ET Q Q q -1 0 0 1 57.02362 339.8236 cm +1 0 0 1 57.02362 241.8236 cm Q q -1 0 0 1 57.02362 339.8236 cm +1 0 0 1 57.02362 241.8236 cm Q q -1 0 0 1 57.02362 315.8236 cm +1 0 0 1 57.02362 217.8236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -4663,10 +4741,10 @@ Q Q Q q -1 0 0 1 57.02362 309.8236 cm +1 0 0 1 57.02362 211.8236 cm Q q -1 0 0 1 57.02362 285.8236 cm +1 0 0 1 57.02362 187.8236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -4688,10 +4766,10 @@ Q Q Q q -1 0 0 1 57.02362 279.8236 cm +1 0 0 1 57.02362 181.8236 cm Q q -1 0 0 1 57.02362 267.8236 cm +1 0 0 1 57.02362 169.8236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -4713,10 +4791,10 @@ Q Q Q q -1 0 0 1 57.02362 261.8236 cm +1 0 0 1 57.02362 163.8236 cm Q q -1 0 0 1 57.02362 249.8236 cm +1 0 0 1 57.02362 151.8236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -4738,70 +4816,70 @@ Q Q Q q -1 0 0 1 57.02362 231.8236 cm +1 0 0 1 57.02362 133.8236 cm Q q -1 0 0 1 57.02362 200.6236 cm +1 0 0 1 57.02362 102.6236 cm q BT 1 0 0 1 0 2.2 Tm 13.2 TL /F2 11 Tf .133333 .133333 .133333 rg (14. The Defect in the Model) Tj T* ET Q Q q -1 0 0 1 57.02362 180.6236 cm +1 0 0 1 57.02362 82.62362 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (This paper is evidence of a problem that extends beyond any single codebase.) Tj T* ET Q Q -q -1 0 0 1 57.02362 114.6236 cm -q -BT 1 0 0 1 0 50 Tm .653022 Tw 12 TL /F1 10 Tf 0 0 0 rg (On April 4, 2026, ) Tj 0 .4 .6 rg (russell@unturf) Tj 0 0 0 rg ( published ) Tj 0 .4 .6 rg ("Stress on Our Shared Heart") Tj 0 0 0 rg ( \227 a systematic analysis of 1,264) Tj T* 0 Tw .998334 Tw (MOAD defects across 60+ ecosystems, 18 programming languages, with 919 patches written. The central) Tj T* 0 Tw 2.218835 Tw (finding: O\(N\262\) sedimentary defects compound across architectural layers, creating invisible performance) Tj T* 0 Tw .27131 Tw (taxation on every downstream consumer. A single bottleneck multiplies against every other bottleneck in the) Tj T* 0 Tw (dependency chain.) Tj T* ET -Q -Q -q -1 0 0 1 57.02362 84.62362 cm -q -0 0 0 rg -BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 2.113022 Tw (On April 13--14, 2026 \227 nine days later \227 the machine learning agent that built uncommonlisp wrote) Tj T* 0 Tw (MOAD-0001 into fresh code. Twice.) Tj T* ET -Q -Q endstream endobj 93 0 obj << -/Length 6975 +/Length 7427 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q 1 0 0 1 57.02362 705.0236 cm q -BT 1 0 0 1 0 50 Tm 1.989873 Tw 12 TL /F5 10 Tf 0 0 0 rg (intern_symbol) Tj /F1 10 Tf ( in the assembly implementation: a linear scan through all interned symbols. O\(N\) per) Tj T* 0 Tw 1.841147 Tw (lookup. The exact pattern described in "Stress on Our Shared Heart." The exact pattern the agent was) Tj T* 0 Tw 3.328647 Tw (explicitly instructed to avoid. The agent had the full MOAD taxonomy in its context window. It had) Tj T* 0 Tw 2.822739 Tw /F5 10 Tf (BLACKOPS.md) Tj /F1 10 Tf ( defining all five MOADs. It had the undefect.com mission statement. And it still wrote) Tj T* 0 Tw /F5 10 Tf (jmp) Tj ( ) Tj (.isym_search) Tj /F1 10 Tf ( instead of a hash table.) Tj T* ET +BT 1 0 0 1 0 50 Tm .653022 Tw 12 TL /F1 10 Tf 0 0 0 rg (On April 4, 2026, ) Tj 0 .4 .6 rg (russell@unturf) Tj 0 0 0 rg ( published ) Tj 0 .4 .6 rg ("Stress on Our Shared Heart") Tj 0 0 0 rg ( \227 a systematic analysis of 1,264) Tj T* 0 Tw .998334 Tw (MOAD defects across 60+ ecosystems, 18 programming languages, with 919 patches written. The central) Tj T* 0 Tw 2.218835 Tw (finding: O\(N\262\) sedimentary defects compound across architectural layers, creating invisible performance) Tj T* 0 Tw .27131 Tw (taxation on every downstream consumer. A single bottleneck multiplies against every other bottleneck in the) Tj T* 0 Tw (dependency chain.) Tj T* ET Q Q q 1 0 0 1 57.02362 675.0236 cm q +0 0 0 rg +BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 2.113022 Tw (On April 13--14, 2026 \227 nine days later \227 the machine learning agent that built uncommonlisp wrote) Tj T* 0 Tw (MOAD-0001 into fresh code. Twice.) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 609.0236 cm +q +BT 1 0 0 1 0 50 Tm 1.989873 Tw 12 TL /F5 10 Tf 0 0 0 rg (intern_symbol) Tj /F1 10 Tf ( in the assembly implementation: a linear scan through all interned symbols. O\(N\) per) Tj T* 0 Tw 1.841147 Tw (lookup. The exact pattern described in "Stress on Our Shared Heart." The exact pattern the agent was) Tj T* 0 Tw 3.328647 Tw (explicitly instructed to avoid. The agent had the full MOAD taxonomy in its context window. It had) Tj T* 0 Tw 2.822739 Tw /F5 10 Tf (BLACKOPS.md) Tj /F1 10 Tf ( defining all five MOADs. It had the undefect.com mission statement. And it still wrote) Tj T* 0 Tw /F5 10 Tf (jmp) Tj ( ) Tj (.isym_search) Tj /F1 10 Tf ( instead of a hash table.) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 579.0236 cm +q BT 1 0 0 1 0 14 Tm 1.541835 Tw 12 TL /F5 10 Tf 0 0 0 rg (list.index\(\)) Tj /F1 10 Tf ( in the Python implementation's ) Tj /F5 10 Tf (_define_record_type) Tj /F1 10 Tf (: linear search for field position.) Tj T* 0 Tw (O\(N\) where O\(1\) was trivial. Same defect. Same context. Same failure.) Tj T* ET Q Q q -1 0 0 1 57.02362 657.0236 cm +1 0 0 1 57.02362 561.0236 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The commit history proves it:) Tj T* ET Q Q q -1 0 0 1 57.02362 651.0236 cm +1 0 0 1 57.02362 555.0236 cm Q q -1 0 0 1 57.02362 651.0236 cm +1 0 0 1 57.02362 555.0236 cm Q q -1 0 0 1 57.02362 639.0236 cm +1 0 0 1 57.02362 543.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -4823,10 +4901,10 @@ Q Q Q q -1 0 0 1 57.02362 633.0236 cm +1 0 0 1 57.02362 537.0236 cm Q q -1 0 0 1 57.02362 621.0236 cm +1 0 0 1 57.02362 525.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -4848,10 +4926,10 @@ Q Q Q q -1 0 0 1 57.02362 615.0236 cm +1 0 0 1 57.02362 519.0236 cm Q q -1 0 0 1 57.02362 603.0236 cm +1 0 0 1 57.02362 507.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -4873,52 +4951,52 @@ Q Q Q q -1 0 0 1 57.02362 585.0236 cm +1 0 0 1 57.02362 489.0236 cm Q q -1 0 0 1 57.02362 567.0236 cm +1 0 0 1 57.02362 471.0236 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL (The defect is in the model, not the programmer.) Tj T* ET Q Q q -1 0 0 1 57.02362 513.0236 cm +1 0 0 1 57.02362 417.0236 cm q BT 1 0 0 1 0 38 Tm 5.336796 Tw 12 TL /F1 10 Tf 0 0 0 rg (Language models learn from training data. The training data contains millions of linear scans,) Tj T* 0 Tw 3.434395 Tw /F5 10 Tf (list.contains) Tj /F1 10 Tf ( calls, ) Tj /F5 10 Tf (std::find) Tj /F1 10 Tf ( inside loops, ) Tj /F5 10 Tf (array.indexOf) Tj /F1 10 Tf ( in hot paths. These patterns are) Tj T* 0 Tw .94631 Tw (statistically dominant. When a model generates code, it reproduces the dominant patterns from its training) Tj T* 0 Tw (distribution \227 including the sedimentary defects.) Tj T* ET Q Q q -1 0 0 1 57.02362 471.0236 cm +1 0 0 1 57.02362 375.0236 cm q 0 0 0 rg BT 1 0 0 1 0 26 Tm /F1 10 Tf 12 TL .029897 Tw (Cantor formalized set theory in 1874. Hash tables were implemented in 1953. The O\(1\) membership test has) Tj T* 0 Tw .363241 Tw (been known for 152 years and available in every language for 73 years. Yet language models still default to) Tj T* 0 Tw (O\(N\) because O\(N\) is what most code does. The training data is the sediment.) Tj T* ET Q Q q -1 0 0 1 57.02362 429.0236 cm +1 0 0 1 57.02362 333.0236 cm q BT 1 0 0 1 0 26 Tm 2.359862 Tw 12 TL /F3 10 Tf 0 0 0 rg (This means every machine learning agent generating code today is propagating MOAD-0001 by) Tj T* 0 Tw .91789 Tw (default.) Tj /F1 10 Tf ( Not because the solutions are unknown. Not because the agents lack capability. But because the) Tj T* 0 Tw (statistical distribution of training data encodes the defect as the norm.) Tj T* ET Q Q q -1 0 0 1 57.02362 387.0236 cm +1 0 0 1 57.02362 291.0236 cm q BT 1 0 0 1 0 26 Tm .412917 Tw 12 TL /F1 10 Tf 0 0 0 rg (The fix is not to patch individual outputs. The fix is to teach models that ) Tj /F3 10 Tf (O\(1\) is the default) Tj /F1 10 Tf ( for membership) Tj T* 0 Tw 4.550556 Tw (tests, lookups, and deduplication. That ) Tj /F5 10 Tf (set\(\)) Tj /F1 10 Tf ( is not an optimization \227 it is the baseline. That) Tj T* 0 Tw /F5 10 Tf (list.contains) Tj /F1 10 Tf ( inside a loop is a defect, not a pattern.) Tj T* ET Q Q q -1 0 0 1 57.02362 345.0236 cm +1 0 0 1 57.02362 249.0236 cm q 0 0 0 rg BT 1 0 0 1 0 26 Tm /F1 10 Tf 12 TL 1.790491 Tw (Until that teaching happens at the training level, every agent needs a MOAD audit pass on every code) Tj T* 0 Tw 1.596373 Tw (generation. This paper \227 with its commit history showing the defect introduced and then fixed \227 is the) Tj T* 0 Tw (evidence that the audit is necessary.) Tj T* ET Q Q q -1 0 0 1 57.02362 339.0236 cm +1 0 0 1 57.02362 243.0236 cm Q q -1 0 0 1 57.02362 297.0236 cm +1 0 0 1 57.02362 201.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -4941,30 +5019,30 @@ Q Q Q q -1 0 0 1 57.02362 297.0236 cm +1 0 0 1 57.02362 201.0236 cm Q q -1 0 0 1 57.02362 267.0236 cm +1 0 0 1 57.02362 171.0236 cm q 0 0 0 rg BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 1.253223 Tw (The stress is real. The compound burden is measurable. And the models that generate our infrastructure) Tj T* 0 Tw (carry the defect in their weights.) Tj T* ET Q Q q -1 0 0 1 57.02362 249.0236 cm +1 0 0 1 57.02362 153.0236 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (This paper is the proof. The commit history is the evidence. The fix starts with awareness.) Tj T* ET Q Q q -1 0 0 1 57.02362 217.8236 cm +1 0 0 1 57.02362 121.8236 cm q BT 1 0 0 1 0 2.2 Tm 13.2 TL /F2 11 Tf .133333 .133333 .133333 rg (Citation) Tj T* ET Q Q q -1 0 0 1 57.02362 167.8236 cm +1 0 0 1 57.02362 71.82362 cm q q 1 0 0 1 0 0 cm @@ -4984,14 +5062,23 @@ Q Q Q Q + +endstream +endobj +94 0 obj +<< +/Length 2147 +>> +stream +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 57.02362 136.6236 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 (References) Tj T* ET Q Q q -1 0 0 1 57.02362 86.62362 cm +1 0 0 1 57.02362 701.8236 cm q q 1 0 0 1 0 0 cm @@ -5011,26 +5098,17 @@ Q Q Q Q - -endstream -endobj -94 0 obj -<< -/Length 2111 ->> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 57.02362 751.8236 cm +1 0 0 1 57.02362 670.6236 cm q BT 1 0 0 1 0 2.2 Tm 13.2 TL /F2 11 Tf .133333 .133333 .133333 rg (License) Tj T* ET Q Q q -1 0 0 1 57.02362 735.8236 cm +1 0 0 1 57.02362 654.6236 cm Q q -1 0 0 1 57.02362 532.7477 cm +1 0 0 1 57.02362 451.5477 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -5046,13 +5124,13 @@ Q Q Q q -1 0 0 1 57.02362 524.7477 cm +1 0 0 1 57.02362 443.5477 cm Q q -1 0 0 1 57.02362 516.7477 cm +1 0 0 1 57.02362 435.5477 cm Q q -1 0 0 1 57.02362 318.0922 cm +1 0 0 1 57.02362 236.8922 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -5068,17 +5146,17 @@ Q Q Q q -1 0 0 1 57.02362 310.0922 cm +1 0 0 1 57.02362 228.8922 cm Q q -1 0 0 1 57.02362 292.0922 cm +1 0 0 1 57.02362 210.8922 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F4 10 Tf 12 TL 155.3042 0 Td (GNU Affero General Public License v3) Tj T* -155.3042 0 Td ET Q Q q -1 0 0 1 57.02362 69.29221 cm +1 0 0 1 57.02362 64.89221 cm q q 1 0 0 1 0 0 cm @@ -5088,10 +5166,10 @@ q .662745 .662745 .662745 RG .5 w .960784 .960784 .960784 rg -n -6 -6 480.0283 213.6 re B* +n -6 -6 480.0283 136.8 re B* Q q -BT 1 0 0 1 0 193.6 Tm 9.6 TL /F5 8 Tf 0 0 0 rg (AGPL-3.0-only) Tj T* T* (PERMACOMPUTER PREAMBLE - NO WARRANTY) Tj T* T* (This is free software for the public good of a permacomputer hosted at) Tj T* (permacomputer.com, an always-on computer by the people, for the people. One) Tj T* (which is durable, easy to repair, ) Tj (&) Tj ( distributed like tap water for machine) Tj T* (learning intelligence.) Tj T* T* (The permacomputer is community-owned infrastructure optimized around four values:) Tj T* T* ( TRUTH - Source code must be open source ) Tj (&) Tj ( freely distributed) Tj T* ( FREEDOM - Voluntary participation without corporate control) Tj T* ( HARMONY - Systems operating with minimal waste that self-renew) Tj T* ( LOVE - Individual rights protected while fostering cooperation) Tj T* T* (This software contributes to that vision by proving that feedback) Tj T* (\(the computational primitive of continuations\) composes into a universal) Tj T* (execution model. Four implementations, one language, 836 tests, 12,774) Tj T* (lines. Code is seeds to sprout on any abandoned technology.) Tj T* T* ET +BT 1 0 0 1 0 116.8 Tm 9.6 TL /F5 8 Tf 0 0 0 rg (AGPL-3.0-only) Tj T* T* (PERMACOMPUTER PREAMBLE - NO WARRANTY) Tj T* T* (This is free software for the public good of a permacomputer hosted at) Tj T* (permacomputer.com, an always-on computer by the people, for the people. One) Tj T* (which is durable, easy to repair, ) Tj (&) Tj ( distributed like tap water for machine) Tj T* (learning intelligence.) Tj T* T* (The permacomputer is community-owned infrastructure optimized around four values:) Tj T* T* ( TRUTH - Source code must be open source ) Tj (&) Tj ( freely distributed) Tj T* ( FREEDOM - Voluntary participation without corporate control) Tj T* ET Q Q Q @@ -5102,12 +5180,12 @@ endstream endobj 95 0 obj << -/Length 1083 +/Length 1542 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 57.02362 588.6236 cm +1 0 0 1 57.02362 511.8236 cm q q 1 0 0 1 0 0 cm @@ -5117,10 +5195,10 @@ q .662745 .662745 .662745 RG .5 w .960784 .960784 .960784 rg -n -6 -6 480.0283 175.2 re B* +n -6 -6 480.0283 252 re B* Q q -BT 1 0 0 1 0 155.2 Tm 9.6 TL /F5 8 Tf 0 0 0 rg (Learn more: https://www.permacomputer.com) Tj T* T* (NO WARRANTY. THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.) Tj T* T* (That said, our permacomputer's digital membrane stratum continuously runs unit,) Tj T* (integration, ) Tj (&) Tj ( functional tests on all of its own software, with our) Tj T* (permacomputer monitoring itself, repairing itself, with minimal human in the) Tj T* (loop guidance. Our machine learning agents do their best to leave no stone) Tj T* (unturned.) Tj T* T* (Copyright \(C\) 2025-2026 TimeHexOn ) Tj (&) Tj ( foxhop ) Tj (&) Tj ( russell@unturf) Tj T* (https://www.timehexon.com) Tj T* (https://www.foxhop.net) Tj T* (https://www.unturf.com/software) Tj T* (https://www.permacomputer.com) Tj T* (https://uncloseai.com) Tj T* (https://russell.ballestrini.net) Tj T* ET +BT 1 0 0 1 0 232 Tm 9.6 TL /F5 8 Tf 0 0 0 rg ( HARMONY - Systems operating with minimal waste that self-renew) Tj T* ( LOVE - Individual rights protected while fostering cooperation) Tj T* T* (This software contributes to that vision by proving that feedback) Tj T* (\(the computational primitive of continuations\) composes into a universal) Tj T* (execution model. Four implementations, one language, 836 tests, 12,774) Tj T* (lines. Code is seeds to sprout on any abandoned technology.) Tj T* T* (Learn more: https://www.permacomputer.com) Tj T* T* (NO WARRANTY. THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.) Tj T* T* (That said, our permacomputer's digital membrane stratum continuously runs unit,) Tj T* (integration, ) Tj (&) Tj ( functional tests on all of its own software, with our) Tj T* (permacomputer monitoring itself, repairing itself, with minimal human in the) Tj T* (loop guidance. Our machine learning agents do their best to leave no stone) Tj T* (unturned.) Tj T* T* (Copyright \(C\) 2025-2026 TimeHexOn ) Tj (&) Tj ( foxhop ) Tj (&) Tj ( russell@unturf) Tj T* (https://www.timehexon.com) Tj T* (https://www.foxhop.net) Tj T* (https://www.unturf.com/software) Tj T* (https://www.permacomputer.com) Tj T* (https://uncloseai.com) Tj T* (https://russell.ballestrini.net) Tj T* ET Q Q Q @@ -5238,11 +5316,11 @@ xref 0001538316 00000 n 0001538522 00000 n 0001538700 00000 n -0001538874 00000 n -0001539082 00000 n -0001539321 00000 n -0001539527 00000 n -0001539699 00000 n +0001538925 00000 n +0001539099 00000 n +0001539307 00000 n +0001539513 00000 n +0001539685 00000 n 0001539931 00000 n 0001598907 00000 n 0001599217 00000 n @@ -5295,40 +5373,40 @@ xref 0001606269 00000 n 0001606378 00000 n 0001606541 00000 n -0001610881 00000 n -0001619771 00000 n -0001626705 00000 n -0001633841 00000 n -0001643217 00000 n -0001655702 00000 n -0001662972 00000 n -0001669127 00000 n -0001679408 00000 n -0001690641 00000 n -0001697576 00000 n -0001705333 00000 n -0001712360 00000 n -0001714523 00000 n -0001715658 00000 n -0001715848 00000 n -0001715882 00000 n -0001715916 00000 n -0001715950 00000 n -0001715985 00000 n -0001716020 00000 n -0001716055 00000 n -0001716090 00000 n -0001716125 00000 n -0001716160 00000 n -0001716196 00000 n -0001716232 00000 n -0001716268 00000 n -0001716304 00000 n -0001716340 00000 n +0001611006 00000 n +0001619896 00000 n +0001626830 00000 n +0001633966 00000 n +0001643342 00000 n +0001655827 00000 n +0001663097 00000 n +0001669252 00000 n +0001679533 00000 n +0001691757 00000 n +0001698672 00000 n +0001706705 00000 n +0001714184 00000 n +0001716383 00000 n +0001717977 00000 n +0001718167 00000 n +0001718201 00000 n +0001718235 00000 n +0001718269 00000 n +0001718304 00000 n +0001718339 00000 n +0001718374 00000 n +0001718409 00000 n +0001718444 00000 n +0001718479 00000 n +0001718515 00000 n +0001718551 00000 n +0001718587 00000 n +0001718623 00000 n +0001718659 00000 n trailer << /ID -[<68a895ef6e6cc348356e330c3719f07d><68a895ef6e6cc348356e330c3719f07d>] +[<8aea0891e8ebfbc48b60770ef7c0f271><8aea0891e8ebfbc48b60770ef7c0f271>] % ReportLab generated PDF document -- digest (opensource) /Info 35 0 R @@ -5336,5 +5414,5 @@ trailer /Size 112 >> startxref -1716376 +1718695 %%EOF diff --git a/whitepaper/uncommonlisp-whitepaper.rst b/whitepaper/uncommonlisp-whitepaper.rst index 234c71e..bc348f2 100644 --- a/whitepaper/uncommonlisp-whitepaper.rst +++ b/whitepaper/uncommonlisp-whitepaper.rst @@ -58,7 +58,7 @@ Abstract 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. -**uncommonlisp** proves this by implementing a complete Scheme in four ways: a single Python file (3,324 lines), a C implementation with x86_64 JIT (9,429 lines, 10--24x faster than CPython), and a pure x86_64 assembly interpreter (2,592 lines, 13KB binary, zero dependencies). A stack-based bytecode compiler achieves 7--19x speedups over tree-walking interpretation. An explicit frame stack replaces Python's call stack, enabling tail-call optimization of arbitrary depth & full first-class continuations (``call/cc``) that support escape, upward, & multi-shot invocation. A peephole optimizer, inline cache, & constant folder tighten the generated bytecode. A portal system serializes the entire machine state (environment, continuation stack, instruction pointer) to JSON & resumes it on another machine. +**uncommonlisp** proves this by implementing R7RS Scheme in three ways: a Python bytecode VM (3,324 lines, full continuations, portal), a C implementation with x86_64 JIT (10,000 lines, 7--10x faster than CPython on recursive workloads), and a pure x86_64 assembly interpreter (3,100 lines, 13KB binary, zero dependencies). 943 tests verify identical behavior across all three. A stack-based bytecode compiler achieves 7--19x speedups over tree-walking interpretation. An explicit frame stack replaces Python's call stack, enabling tail-call optimization of arbitrary depth & full first-class continuations (``call/cc``) that support escape, upward, & multi-shot invocation. A peephole optimizer, inline cache, & constant folder tighten the generated bytecode. A portal system serializes the entire machine state (environment, continuation stack, instruction pointer) to JSON & resumes it on another machine. The paper further presents the EML universality proof: a single operator ``eml(x, y) = exp(x) - ln(y)`` with the constant 1 generates all elementary functions (exp, ln, arithmetic, negation, complex plane access, trigonometry). Verified numerically in Python, verified in uncommonlisp's own bytecode, & proven formally in Lean 4 with zero ``sorry``. @@ -554,37 +554,38 @@ uncommonlisp provides the runtime layer: a language that can checkpoint its own *"A diagram is worth 10,000 words."* — russell@unturf.com -uncommonlisp exists as four implementations sharing the same ``.lsp`` test files: +uncommonlisp implements R7RS Scheme in three implementations sharing the same ``.lsp`` test files. The language is Scheme (a dialect of Lisp, designed 1975). The project name plays on Common Lisp — this is decidedly uncommon. .. table:: - :widths: 25 10 12 12 12 12 + :widths: 25 10 10 10 10 10 10 - ===================== ======= ========== =========== ============ ============== - Implementation Lines ack(3,4) sum-to(50k) Binary Dependencies - ===================== ======= ========== =========== ============ ============== - Python bytecode VM 3,324 93ms 515ms interpreted Python 3 - C tree-walker 8,120 29ms 105ms 171KB libc - C + x86_64 JIT 9,429 0.2ms 0.35ms 171KB libc - x86_64 Assembly 2,592 7.3ms 43ms 13KB none - ===================== ======= ========== =========== ============ ============== + ===================== ======= ========== ========= =========== ============ ============== + Implementation Lines ack(3,4) fib(35) sum-to(50k) Binary Dependencies + ===================== ======= ========== ========= =========== ============ ============== + C + x86_64 JIT 10,000 0.19ms 0.09ms 0.55ms 171KB libc + CPython (reference) — 1.3ms 0.006ms 5.5ms — Python 3 + C interpreter 10,000 20ms 0.06ms 109ms 171KB libc + Python bytecode VM 3,324 149ms 0.75ms 437ms interpreted Python 3 + x86_64 Assembly 3,100 8ms* 0.6ms* 43ms* 13KB none + ===================== ======= ========== ========= =========== ============ ============== -Assembly times include process startup and parsing. +All benchmarks measured in-process (no startup overhead) on the same machine. Assembly times (\*) include process startup + tokenizer + parser. -**The JIT compiles Scheme to native machine code at runtime** via ``mmap(PROT_EXEC)`` & raw x86_64 byte emission. It handles ``if``, ``cond``, ``and``, ``or``, ``let``, named-let loops, ``car``/``cdr``/``cons``, arithmetic, comparisons, & self-recursive calls. Functions that use ``call/cc``, macros, or complex forms fall back to the interpreter. +**The JIT runs Scheme faster than CPython runs Python.** ``ack(3,4)`` completes in 0.19ms (JIT) vs 1.3ms (CPython) — 7x faster. ``sum-to(50000)`` completes in 0.55ms (JIT) vs 5.5ms (CPython) — 10x faster. The JIT compiles Scheme AST directly to x86_64 machine code via ``mmap(PROT_EXEC)`` & raw byte emission. It handles ``if``, ``cond``, ``and``, ``or``, ``let``, named-let loops (native ``jmp`` — zero call overhead), ``car``/``cdr``/``cons``, arithmetic, comparisons, & self-recursive calls. Functions that use ``call/cc``, macros, or complex forms fall back to the interpreter. -**The assembly implementation proves the language is substrate-independent.** 2,592 lines of GNU assembler, 13KB stripped binary, zero external dependencies. It uses only four Linux syscalls (``read``, ``write``, ``mmap``, ``exit``), a bump allocator, & tag-in-low-3-bits values. It runs ``(ack 3 4) = 125`` & ``(fib 35) = 9227465`` correctly, 2.5--4x faster than the C interpreter on recursive workloads. +**The assembly implementation proves the language runs on bare metal.** 3,100 lines of GNU assembler, 13KB stripped binary, zero external dependencies. Only four Linux syscalls (``read``, ``write``, ``mmap``, ``exit``). A bump allocator, tag-in-low-3-bits values, 71 builtins, & TCO via ``jmp``. It runs ``(ack 3 4) = 125`` & ``(fib 35) = 9227465`` correctly — 2.5x faster than the C interpreter on recursive workloads because hand-written assembly avoids C's function call overhead for eval dispatch. -**Key finding**: Hand-written assembly outperforms ``gcc -O2`` on the same algorithm because it avoids C's function call overhead for eval dispatch. But the JIT outperforms everything: 33x faster than hand-written assembly, because it eliminates the interpreter loop entirely. +**The bytecode VM delivers 7--19x speedup over tree-walking.** The Python implementation compiles Scheme to 40 opcodes (plus 20 specialized & 5 superinstructions), executed on an explicit frame stack with inline caching, constant folding, & peephole optimization. Full first-class continuations (multi-shot, upward) enable generators, coroutines, & machine state migration via portal. 11.1 Test Coverage ^^^^^^^^^^^^^^^^^^^^ -836 verified assertions across all implementations: +943 verified assertions across all implementations: -- Python: 571 unit + integration tests (``tests.py``) -- C: 76 unit + integration + JIT tests (``c/test.c``) -- Assembly: 75 unit + integration + functional tests (``asm/test.sh``) -- Shared: 114 functional tests (``tests/functional.lsp``, runs in Python & C) +- Python unit + integration: 571 tests (``tests.py``) +- C unit + integration + JIT + continuations + portal: 83 tests (``c/test.c``) +- Assembly unit + integration + functional: 108 tests (``asm/test.sh``) +- Shared functional: 181 tests (``tests/functional.lsp``, runs in Python & C) All pass via ``make test-all``.