From 5ce42a7089b353ce3aa9dc634b4bbf624b85ebef Mon Sep 17 00:00:00 2001 From: "russell@unturf.com" Date: Thu, 16 Apr 2026 18:11:32 -0400 Subject: [PATCH] whitepaper: extend "feedback is all you need" across 3 scopes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Major revision reflecting current state. The original paper argued feedback (continuations) as a universal within-process primitive. This revision extends the argument to two more scopes discovered while building the cross-impl portal system: - Within process: continuations (live stack) - Across process: portals (serialized VM state) - Across impl: Scheme source itself as wire format Abstract rewritten around the three scopes. New benchmark numbers (asm cross-process round-trip 1.5 ms vs Python 260 ms — 160×). Section 4.3 "Three Scopes of Feedback" added — the key new framing. Section 7 "Portal: Feedback Across Time" rewritten to cover all three formats (S-expression portable, JSON graph-aware, binary heap-dump) with the 3×3 cross-impl matrix, cross-process benchmarks, and mismatch-case behavior table. Section 11 "Three Implementations, One Language" updated with current line counts (4,455 asm, 3,678 py), binary sizes (22 KB asm stripped, 205 KB C), and builtin count (79 asm). Section 11.2 "File I/O Parity" added — the minimal file vocabulary that reaches parity across all three implementations, including the asm port encoding trick (SPECIAL values ≥ PORT_SPECIAL_BASE). Test counts: 974 verified assertions (was 943). --- whitepaper/uncommonlisp-whitepaper.pdf | 4213 +++++++++++++++++------- whitepaper/uncommonlisp-whitepaper.rst | 277 +- 2 files changed, 3191 insertions(+), 1299 deletions(-) diff --git a/whitepaper/uncommonlisp-whitepaper.pdf b/whitepaper/uncommonlisp-whitepaper.pdf index 9c26cec..9150452 100644 --- a/whitepaper/uncommonlisp-whitepaper.pdf +++ b/whitepaper/uncommonlisp-whitepaper.pdf @@ -2,7 +2,8 @@ %“Œ‹ž ReportLab Generated PDF document (opensource) 1 0 obj << -/F1 2 0 R /F2 4 0 R /F3 5 0 R /F4 6 0 R /F5 9 0 R /F6 14 0 R +/F1 2 0 R /F2 4 0 R /F3 5 0 R /F4 6 0 R /F5 9 0 R /F6 14 0 R + /F7 18 0 R >> endobj 2 0 obj @@ -54,7 +55,7 @@ endobj endobj 10 0 obj << -/Annots [ 7 0 R 8 0 R ] /Contents 81 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 80 0 R /Resources << +/Annots [ 7 0 R 8 0 R ] /Contents 90 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 89 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] /XObject << /FormXob.d3ecd28ca03f587d6940049748681018 3 0 R >> @@ -66,7 +67,7 @@ endobj endobj 11 0 obj << -/Contents 82 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 80 0 R /Resources << +/Contents 91 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 89 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << @@ -76,7 +77,7 @@ endobj endobj 12 0 obj << -/Contents 83 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 80 0 R /Resources << +/Contents 92 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 89 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << @@ -86,7 +87,7 @@ endobj endobj 13 0 obj << -/Contents 84 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 80 0 R /Resources << +/Contents 93 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 89 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << @@ -101,7 +102,7 @@ endobj endobj 15 0 obj << -/Contents 85 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 80 0 R /Resources << +/Contents 94 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 89 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << @@ -111,7 +112,7 @@ endobj endobj 16 0 obj << -/Contents 86 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 80 0 R /Resources << +/Contents 95 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 89 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << @@ -121,7 +122,7 @@ endobj endobj 17 0 obj << -/Contents 87 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 80 0 R /Resources << +/Contents 96 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 89 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << @@ -131,17 +132,12 @@ endobj endobj 18 0 obj << -/Contents 88 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 << - ->> - /Type /Page +/BaseFont /ZapfDingbats /Name /F7 /Subtype /Type1 /Type /Font >> endobj 19 0 obj << -/Contents 89 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 80 0 R /Resources << +/Contents 97 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 89 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << @@ -151,24 +147,27 @@ endobj endobj 20 0 obj << -/A << -/S /URI /Type /Action /URI (mailto:russell@unturf.com) ->> /Border [ 0 0 0 ] /Rect [ 248.0736 332.6236 334.3536 344.6236 ] /Subtype /Link /Type /Annot +/Contents 98 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 89 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page >> endobj 21 0 obj << -/Annots [ 20 0 R ] /Contents 90 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 80 0 R /Resources << +/Contents 99 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 89 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] ->> /Rotate 0 - /Trans << +>> /Rotate 0 /Trans << ->> /Type /Page +>> + /Type /Page >> endobj 22 0 obj << -/Contents 91 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 80 0 R /Resources << +/Contents 100 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 89 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << @@ -180,12 +179,12 @@ endobj << /A << /S /URI /Type /Action /URI (mailto:russell@unturf.com) ->> /Border [ 0 0 0 ] /Rect [ 248.0736 449.0236 334.3536 461.0236 ] /Subtype /Link /Type /Annot +>> /Border [ 0 0 0 ] /Rect [ 248.0736 104.2236 334.3536 116.2236 ] /Subtype /Link /Type /Annot >> endobj 24 0 obj << -/Annots [ 23 0 R ] /Contents 92 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 80 0 R /Resources << +/Annots [ 23 0 R ] /Contents 101 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 89 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << @@ -195,35 +194,48 @@ endobj 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 +/Contents 102 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 89 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page >> 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 +/Contents 103 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 89 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page >> 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 201.0236 417.502 213.0236 ] /Subtype /Link /Type /Annot +/S /URI /Type /Action /URI (mailto:russell@unturf.com) +>> /Border [ 0 0 0 ] /Rect [ 248.0736 523.0236 334.3536 535.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 201.0236 487.672 213.0236 ] /Subtype /Link /Type /Annot +>> /Border [ 0 0 0 ] /Rect [ 134.8436 138.6236 202.0657 150.6236 ] /Subtype /Link /Type /Annot >> endobj 29 0 obj << -/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 << +/A << +/S /URI /Type /Action /URI (https://undefect.com/public/stress-on-our-shared-heart/) +>> /Border [ 0 0 0 ] /Rect [ 247.8136 138.6236 385.3838 150.6236 ] /Subtype /Link /Type /Annot +>> +endobj +30 0 obj +<< +/Annots [ 27 0 R 28 0 R 29 0 R ] /Contents 104 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 89 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << @@ -231,15 +243,39 @@ endobj >> /Type /Page >> endobj -30 0 obj +31 0 obj << -/BitsPerComponent 8 /ColorSpace /DeviceRGB /Filter [ /ASCII85Decode /FlateDecode ] /Height 523 /Length 58769 /SMask 31 0 R +/A << +/S /URI /Type /Action /URI (https://undefect.com/public/stress-on-our-shared-heart/) +>> /Border [ 0 0 0 ] /Rect [ 293.562 267.0236 417.502 279.0236 ] /Subtype /Link /Type /Annot +>> +endobj +32 0 obj +<< +/A << +/S /URI /Type /Action /URI (mailto:russell@unturf) +>> /Border [ 0 0 0 ] /Rect [ 423.062 267.0236 487.672 279.0236 ] /Subtype /Link /Type /Annot +>> +endobj +33 0 obj +<< +/Annots [ 31 0 R 32 0 R ] /Contents 105 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 89 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 + /Trans << + +>> /Type /Page +>> +endobj +34 0 obj +<< +/BitsPerComponent 8 /ColorSpace /DeviceRGB /Filter [ /ASCII85Decode /FlateDecode ] /Height 523 /Length 58769 /SMask 35 0 R /Subtype /Image /Type /XObject /Width 535 >> stream Gb"-6G?bhRd.iTHHKKV;S9*7;?q-4+'=2>sQuc%9W4VOEt5+"MMd4I@K6]a#T+0$[iX^XpGYnBb\U(!cg3:0pQ,3AlqHU,Y3N0mqXMIRQ%XgD\@B&qcqo4As7>F"n(kU"eZ)VJVG-7+Y@$VHXm=Q?>IJA$]Qs*\aH.Qjo&Os2nAfY8dcJQ4UN#2/jiWjh?+]f;J,Rok6O.7:kHSO;cCI%@h7@_M*Zc\(S@F%HH=1.=X&lK6@q4QZj"4PT!s8W-"*K"fo]c2Ck8,dXgot5)^juTga]Q&l@?W$4/A#5MP9NGQp?gVH]"6b3HhYF5&!h*%!s8XX?O3$ADr8:BCtZ,J[;/um2;gj1CtW&u>cqGK%Vh6)>M$YU'>Aqo)B0V7*Zc@:']eH?GPUgk'.6P"H[C*aGdtAtDr/-Pe##k/?T0pQSND%AH$LDjEoc#dF7<'%qtiU+q@m7pM2;6b*ood`=2hs%q>C'[c'pY)cCC:M:EE/)q:a8i5m-nfi,c5HP8b@cnEnu>[r:0\\T>g?drX6MBhhDu>(!X[$Pmi+FRKQ.?5JFi'VX)6V"eZ;o;q]N7pRPejbdMdLrQL4kX"!t[2rsie\ace)":7PFtFD8pI2(;J$CtlDc\om=(joirJdVWK%0qLLQZ=(M#e>ZBQ&#u^6ZT:'*$lqBNfs519p[5_6iPOE_GCtO#6#LuBmbNX/+$`+e84W_$q>3t+`=W"M5J^#'c[_Mf$IQnT+62A?U8+J.,9oQB6D19MDM-AcqXeJ5^"0Ao5CND#^4#l:CtLFCY$C>T#9_:cn)%?L0+877H2[U4JHH/VrV'YOK3ULLGON7qs8LBl:upq#8;,IiG4p4`"ac[qm-Da>"MP>98k0,RR\-sq6oB4Gd/mXnl9,?g]e:R>Zfb6P:O<-"0M?]T%\T-fXSU'hhj4i$Q!^-TL#JNSV@Oj12514))GmKRl>9%Jd!8X_LLaoSNCoT9G\M3OX!BildlYhS0gt!<2rnHB?m"uRECe*c'gMo+Bl?^%9U/^k>(3cSQ5?3ZY%I*m+Ck#l-lhC^KS5Dgk^cB!0%qt7bA!E:7\\4OUZaS*^+i![;/iD+)1<,aZFV.!!:KcM\i!KHPRD6a*tDirVLg6j<:M,YcrY.J90o!\[f8e9%:M!F%3PC(,)%N\?qNPDL`_@B@!0.))Dp!El!>2=0,L)KA!]_%18b>5d>([]!^3LWDf]iE,`%XbA33(J[r@3j2Q`oC"94`=05Y;WI%EtM2ZA^eZ)&?C_J6rVHgZP-*0r>(Z%ClDr/-p4aT(q\&(8%0j7]'7oujl].eLCQR$O%1NJ@K&e-s1M2TLYHJZN6I8u3USE6bI$QEm?FOfX_Dqk":n[rl6rmD7K9n5u%NIHiU_Cq9.HB[WBpe)^q"Z(<]m@(aV+Sl^G5hDb9:+-NM#`b&S2kZ7I\bGi9mcNrOYmuY&G#5C[hg](m,#FfA]pB-CPeV=EH`H]#c[YWQQ)2Ys"+3fshU\l;n*f_K`NA`9[r,3K>Zmcbg9bQ-)&^OZ?\;^C1M=u]J"aQ&pV(_3Nih1VLBRi^^nj\jOr3.ZXB>#ZfsA+nA_SLV,_X,4W-\.%+A:JKXh$/m^4)7.d+HsDD-,!C5Kp?dYJ,L#k>Za97e-Vs@`'$)+')Dl-a]_U-\>N,Tb$t\>0H[#8Si>+"KR'!%;:J6t(!s]l1H8I`HS:--I'YM,m's]>jXOtFG%iKFCpncWWICm@Pg:MQI;R1t?"-ued.*Z(;?F"*5P$C\_MN8iD/m,?nm*n(Anmmg_oI1EshE?5Z`61ukI!I-?YHKVFkJF>`pmq6P)d:RNuW3#OP,95nih`JPDl7M3_u^V]Pm&.fE"Vb\DrY8Fu;_hj$^,UOjaG^,UH7AiqR*ZZ9':Q]*rA#E(mC:6YuL("qhNZEkp>^gHU&YN'.PNUk42M>[:VY6-5'NUYiY*CICPn9.hoRqtp8+V\DBJ]Y2!WUe%3KM&ed-=JOZ$*C<+\c(5EPDVb0.M\l5Sa6]dV/TUOLT(Jr#h=2%j%fU[Alia.],VH]Y%?=Y"W;6,-2IcJ.p'H0nH'E]9q+&kX&kA[?!%OnFj^Y)!ORA^m\s*\\o[%pG.At&J5V(IX[s&bCppf5%0qc2k=):4+jA%0)'DJar.o5ESeH[06u;=%-,1Z&$fIrCI?_`q"!OigpqJT?;I%K/^3;5IWG>ZmJd(]PJ";@h)^_mr9qE#Z=hKY;(?-(9q'#Qd0:k$\8\-\iPH:,)//4@Y3K&k?>XjYoA.$&,kngNSBdZeC[)B87('=3bKApqmbBhiZF2cr?b`c!=YO=<062Zk72PXC;@FEu"PL20p?\3ajtf?Pc3r`*QA^`VS9dY>R$$)X]i-\1jqhODr+18;t)fj-.nq\$bci=[`.RaYJnN633[StE_7)_(8ep(d"IuRH^[sH5(*-U*(C=cX&mWncVJE<`5KT=H@!HV,?Z(N,8(%(8oEFo5n`f^%*W"u4d9;0aG^$_InB>>N!.LZkPYP_VeFJPauq_6rd7$k3$_,^OsNcZCP@VmXG&m!E&I+8X]oOIe.Y0F%fp:cEokG8-C?5\-:2,oM.(Q8lb\>`*4&Re,0GVfV+Z%#gpqn4qLo:n:6mH!g#o\ScOO+YI&+rP0*a3QVVg=i?r]Bp*^"[DU-o;225jnj?m&r0_*A/q.>pC(i*PF%RlIC1!\(ijG*fZ>63QkFb@dXfmO%o7Uc$b9\[!m`Nf_Be5iW5\@B&qF]Lgq!_aDNao6&+^G&S82"Em2r57,')^[BN`WF;P2fHX&_WLoi%[n*]jjgD5NugHqH1Ro;9Z4uloCAjjl0R-3MgHl,OH:%#%`Ahpi#?>!jR`!U]4)snb$OZP6g9MC[l]+&M8Q^=&ECD$?In:1dRNZL>5q;R\l>Nfh"2'aP>EbsC45q^j>Vb^5=CI4]:GkE(u4onmZ'"q(/#po#4u0V>D7"$qrfFEGIMR5&3+.W7`uM;eGP4*9\ZXLnc@"K8Gq%Y3D(??$s=Wt6COZD;=8I/*3)If9*MD6(WT]Pugr%7\26_;!_6Ha0[[O^aRJCXf96Ea_/'M`/EB$FMeC=P4Zg;&625C^E$fmjWkZV*#smbEptH-Md8/1FdZ0UrjF'Js^_R-qUYR?oR6C,6"l+!=C"0=KC4h]o`GO>mW)s1mGX-Si;Nuj^PKpgWMh4<.UF^ST"Q_\"Ca2Q#OKn[>moB".3ad_5#GOO*lhC)6q"CpC*/>ZeB@nbYbH2d`P6@6R7eL9i8XA/W)?UV54c&@I`'M*P;03,$:V9AN^K&"/D=0E[3A5->lB$;)rG=(&rGAf'F%miu_J]Po'3Nr>/VG6)JF__#4O?uV.gUE5F7UNoZNK0#/%M"6^!i.9.(l0_.pO2i+JQLf[&YP1sc^l`AT";lr2F,?O1T.`-G4+/-Qlpd/p$:3oF660EE'4$no4PVERM#8GNhDLX)ho]:9UWboqA/8Q_hSS9W7LtWM#Er0I>Wi:#RC]d+hDsjk(sa![VXX&@)7FuFKmS>"Yg%c3]oP&eu`0Rp[;IpABBoV6iQoET8F@6k0BMZD;)@KnSkL-WNp*Y#,6I>7ZD`floBLjFE_s'$PtDu"U0HdDRKJscCR0Lf9dU#*gSG7Y7#fGc/7F9dY4tZ,^3VK0cP^qKXeNOPGpbJbREk&>8CcjKHeE=p[6kFkXl1I>NaF&+KE7eFR%@)OO"Z%2:YU#8p3cVk6CII(PBnDT"iQS"[j+&P!&!VMj)PjQ_b2mqj;$=$kBWLF'UWN`T\QrHS8)C;;:C;I[brp/_/#&B*6:(e0P&jW*14*I]G_.Lu_WD@dJ'L9mL";i_HoE;O>_0]0uD!\cXn"QSPiP4m^n/(j]YCk#IrVC6uD.^kNTi%RS,=ddL\8gQne#+9MGjsk?)n";'TVcbqLlL,(77Kbh[937qjXF_M(aN7jB%[/8-gI$`+c'pX&7&,nk99P7@N#=E0DVTL7q!k"RgqS?2:-FBk%I'hgf[qTSYTQUXe#,th3BMt6=`.Tik3e9q#A)2N=gBZfC=OMMZ\+q,j\tQ:3QK1\qtTrF*^*]%P&nRX_#Y>#!s]=k\T8#,46St%q$m=4')=eZI.lopYHP.=[l8][X]r88Fnf(35_4\$+)9+:T*Jh`OZpK_.M7Ip'k,MF^rqbq6IRF*aE-?CgHM"-c"(mb_A,RRUC5+AX^+@CX:S'\jcj@8bE_DraFX1a2Df8G73WnLpNV]JmkK_je!9sjDMR(E(30*Bp_3$Pj<-#D,hR'6UH_\[#ei"ttR7T0.C>*==f=bSZN&_4$i>9,>V`TN0Z+7jeKM)C/Jb)Du8+4(#j#rHQ0+aTdQ9[r:/91b$bB4aZ)#IGN`8Tt=[HI][E0.G1YSLPJ72*Zc@I7uf-+\hpUVd>72E\$Pkf1=1Rk2f:&9@-u[Up[$Q8UQ/(XJ3aR3/-sI^Oc_pq6(n)p4Eti4g9iV%rr)TKE]Y,LOWm4$:jKS;:'gjYW`H7EZ$:p;Ts+mIq1.#:VN`;J4@kdN7#;Q+:>K?5jOaiLb*FX&V:JL@;/=aaTe"$!^\u`e?bcR:pBLp.F.$<"OFp?ed\TTXkKX7%Kl;lH1O/Cs5H?Oe<"il$ZU"q51sXrX<-khV[;=PD[pJfLHaHhZqkE8U_D;`f0h=M/luT0@Z/cV;>7D;%qp.a#ise#,3,ZZYTbK_`J70:.J1^-Que(HEdiqXi:V#&+=Q$,mMMpl^2ZJR,m2cqDHb/Lqf)-BgD]m=hlj@T-:jUU*'U/%7?YdQ`Cps@_iAdo#+ET2Xpdln-n_o!Z%?P#nrK_P.I-3;Zril-h>-;BZXmD6o31#nrpLKFa7'T[1ga^)W5dNP#Fc'gMlo93--`r`5p3a%/Mp$Ao!b?ql)9s(/DWDf_Ta,fPjX/nQQ6:+dVfS'\LQ7cIsW`?+,C")WfbVEbPo^:NS6r;jk[a%`bTGI;lcC[&W<4jeC)8HhS!q/,1@r$NPJ^olOV#GcN=P6R0o\m]Q./8#k09AY4[%ci"&0lE0[Of)a(0DM?srq$77G$\g9P9_m64)Tfs51)hnK&H'e?Fl\H3tRVD]8FH@:0g@%<]i*2(f6tsNRXq+PCIeeEoj<(ZY"t&*Cc)2%I10QLW>f=BDh]*JqJ\!foI4>>3_<.O,q%tkn<")(^CBi'GR?$nV.JlOuEsZW\f,qJ#@J@A?:K0!B%\1?:r%B5!+rU:KCI4&;LNKhaWSDJbj9jk6A[866+=tT0L)?s'E2k%`H<(`5T]DqXb*VB:/=-`N0,5%N;f9X="MAk,P4R\S7QP[gSqAHNNu-!;('R^rV&"d?/90_e_Q?;6UF]Qs*N:4EZ\%'0]$Jp_ups8Mn6Khn:&r!c=ES>NIhLYBEU8`*m_C=TWbingG#&%l;($5I"a`HU\$_7e)fZt\!DYSd-&h(rif!P83CIJ]1^bA.1^",)btOQ"*4.nh9e;,JV'/76,]mlWL@c5a67fsGH,T$H-%F4I`,2rmZ*?bLbSSYhI/:PB,jppN'^M48;-c"G:iV48%Z9'=KjZhQS!?soWbDr/-(E$\,NP!BAeB/1Bl:#3C'_pc/:jU,"gYS%`g-Wr*&Q31S]H'C,TiX!YCS`&F6jit06=gQPe@5KYlY['R_6X^%YS.c)8(gtoFTTbQQhq>)LhnEiD.*EVr=QJauUjJ:3'.-O$Fn=`iEiUQKm-X2$*'$?kMn"9:Ic[@8*&q>>*sMqa/97ZLC!reS2Vdlnn^1`^qk)fNWb*Nu>N*hr2eR"FF\%8\aIYQ,g7sa6[r1a//V?m4Gk#(OFqH@4hnFM;p:._RiBfRA`!-DM8I:ah7Z80-3D1>UHs#egR-NkZS#=4nQR,9?gB'@^A&"YF_0GcI--;ELP@e]Fm9Z)P@Vq,Q$aSa\97*Qqil?lfJ/Q%!WrPpG<9p15h,j&i'EB$VG'SET9d0U`)$U!OR&moV+[kH\SPY]?m$T&Z]QJ&NjuSYnjJ(^KA!0@,tjO8Agb-gp"t9!;)NkA,_Ib&0MdfF-uSCR,Y"of&NMfI?+Y8;Hm]gL(f2H&``fBA.Iu3o>jf&<<(<5qBE@AHVak&hP9pb5O?eYZM&A*]6o+&_\MIN+&J5WAXX$BdOh.'0s!^mDcrJ-%^qdb(K*MqVl,D&tOjM;Ma,_=qVo0cJMNAWVdT4rTh4:tTUcEDP!1jS+jV!nS58+niA0B2:3[edpXEYr4Q7\l4Mh-G1!J7*Jm>)?!8D`IinlM)i4`oma49^V896,QsK;ZJ3q/Ya'4Zkj:[$!]!RPi3nQ4,fa(h+@")"9uBaiTi#>=dW41,4Br9O:mo?\f[Br(>91/C)S^Nuu]EPm"[BmnT8=U.("0f*rb=^q`2C:7aS):H5SgR!hi[nl@>WD,re_4n1qM3+i*bodcX)TgOT;d]?Z^/pe8"Qp,pZ8Z%Ygdu8>Z!s8YmOM!ee2?ZVMqXrMh7^Z8mhnOXo>duJNaOI1f)/B2dm,#Dp8N'A94H+/og"T$@eu`0$jp8YT^Y#AU(RA5AY`k01&/uPr,1F5PpF]^\i9fq!k2s*eeZ&c\(qi9c2"=m3;gW7^JNB@4mHS05an`l3qc_E,bjb/'#r+45&@YN3`CILCP>dkNC*Za'K,U8RTYH^OAh<&6]BIK$=g9bSYWa)Gs*@.Ug[r0S>,mHSG@RMB^0HLM*5_0!lYO`]`R!SGjR5/=Z$WEil&L[sZ1C?eFk09B(_hKUAUh%T1M\[o8p%=#1K<@9)Z,FW#JYE/S14B"@aZrK),=[W:rqneNqBg'P`K4\r$uXA0I25(".H+#E4*Bha2N^k37NmUn\o`e34=8@F4j0[5"9oAXXDD5)k2qE212"lP`[VgmJ9dXFpb,RC9V>O=9#tZoW/Aon5Ms,!'1?iWZ*]#\IOeYqTS418?E?uig9k]<5(#=J2HGakiSt7P$JN"0A#2e_'[#q>hgbP#qeK&ZUrp8kl]=#h4JIgoN!,-'Due)O`ufeu]osX1UIL6)e5TR5iZ>m5VbYJb0nL%_fH=XHmFnD,S`DAOKoI_fEaZW;]6CH!#?@p3H2$a_(3cbhKD*-6#GXeM2ERX@KV(JYhQismF8GNCL!kRY&0;mq>@HH*3dUF3_hJW^b#>35*U:FZ^DcV;++DV$[D.0XN)g=IN@"C6bZYdHHCIO$@p\,V3fT6`Y\7qA.t_M26t$euY9E#sgLqs8K^.aqc!<]kPrmABC!+QE>H(k/"mMQ7A@5J`#]REo`&;PH_R,\@@cjI=($\A)!<3rVQ?4oh1Q"e(n=HDG29_SX0)f<-].QooZbgqS>Gcb^5+(`3P4LLcgd]Y#e$3i`IGWMCN\p>X&L$H&,?[F66hlpqJ:?AN$m7UDmK@/f`Y99+HQ8:6m4i1BkGK4c)"ppl##ks$7\QS.+UbEjed5^GVBqW-r,W\E_&I8b(fh`s*)@`8[)fC**uX&5Vr??/kB6:4*l>rq9TR;'!>c)U\(W"KGIPn4QM_I='"TgX_MAm^,JMI]?BkCf1Y)NZ[``b3VhO_7t5H?CJ:8P&)CZZ_q>0r&OXY/J@q+)p@4WRK/-6N1cC?n>?!rpS/gj8sI/.f&6\30bp(dM@="Qdp%OEbOmP!1.*"Y5;'WCrj3JqfuFC_JS$1]SNKaJP]hDLhE;#h%XGAN_TpUY?G5:6/CD8@-mE!M%N?B8Xum4!DUm!,@cHbMJD[N_iLE-kag`eN9Q+[iG=JCjk/C=Pr8@2RWfG!10D:mIRgr2q,!K_HI+c"lRlV:=W,AU4(?Tk#g,*rRU*EJ*I$G=rNI'eW?V5(%ABC"rji`uA.7Zis8daiKa,V1>'n7`%nrs8f91tVp]"l"t/)*r!rql.rVFu!/[F9X\M56g&9a,_raV)#g5'FrgR`LdHS([/t,@EMBR0I\VH[ADos1s'*MA5o`h.b[ftDb,\T?q[H$S5WFXnX[K%Ejd<)ci!>.#XIV7t]EgWu?k[;$GC@LI_+o^(6e.&X,Hl\#QX3d:#Yi8@Ga[K-m@ROAbG?=E_ki>P=PNrb?gKb]tHR=PtdWggJYCl;<4"<,h2(/S6m2:YLpX\*tSt`.m?XE]LGQ*FQm1Efs,$W:f%]rW'6#K`fDY?k7Ys$]_FL^%n2+aZ&6]6E^A'Ft^E/#i!04*M0[N85uP_1MuOV3S(2Xm''t&JeG$Jn6LK:N\?,(iZi]KXq!X(C'm->!5L-R*#G3p4(i>i2QRl>7\Pq&%WX_$\^ljTL?7DU7;0OY$GIf&j+PK$TIFq,KO+Dr&WRCQqSRZ)YeI8#Tq,ACqK`%5;WV>`j)`gE3H"UiK7K"Jah0k1E7iI;G?Y?m3t[Y'27hb+;!F'cCtjfcGui\_cZJ6CLYgKX(;V/Vs0FmE(^(R=shR]'2b''Ot$mN4afkh39iY6IiNJ,]AdNZI.8gWu?J%nRb,F^lHfJN6I1]b5gLrKK<8Q7UN3*'AJM3%9&qGPi=TX2WESZAL#dDF968)N$'9jNK%5YIQakh^m@ut:8t6$W)3^*'Tc#Rn%\mg%,A'ub8,te/R#MPd[E3L/oKjtS_:;[A#hO7]6bEa`*IF7$4iT+F@/4IgP2,tYgJ0Z@`%FabF3qNV6*3m(P97mEX`.g;m:H_h4ZY'g/#[+]Y-'Dl\NZF,N&Q%#sD1[PL=)`a`aGCQXW/LEDm9:hnj8n'7!\[^KcCI%U'fQ0Q)4j"tB#nK5l0m-U!3$TLiTACSF6WF\O:Z&;B3tP>"/(d=+-_:4%Utf1;LeZ<(FTkLm+Le%"c='I.U9E9I)h0`_^/#H;PZk"G\n#D7heX[IM%[dIs`mT2bm0W@j!QQ28g@Og[T;9V*"8D537SbSD-NK%N9WMWCZ1):B\i,a$`2>r3?bYkr+8\scHZPfes:p41g,ion"Ag#D:+k;g>P[fUe/^!&p#4r^l(P42u.QIWUnj#aD:7[+L*L\0@$As$n$&Xb'^4603hRn-uEp!q?:P1rc"sHPeS%9n_O@WB-G7d]d=hrE^3T=ie'kX,[;'I6KuGZ!0i@M-W'p\(O!8ljI)TsVZpBjQNq&Hh60:#BN0ZUt'4XE4,g]uro]](7iHK!=1(s3So4MCH'!CEW%NZ'$TaJm:_k]2G%LilTP'\9Sd'$e@ndT,$.g9sHE>or?NaJPXVK1e@+B_!#aMl][+'2NF[WIgq`G;I0lB\0DXW=f..pKuu_G%4VEK0L>\DDuFBJKQ6;H\2M3kaUN1jp7sfA!QT4RR#lCfGQl"jTu;&PAJbc04%JN#.(A\?N&fLS%a2Q#o9q)niL[a/3&d*GYg^)!)+I4hW:AOJB=Y-qB\;I0I-cdI%.U??]4MDOfP4%Rro6Pb1HS394HGJkm\bAkYY63tPe#10B($!iN<_hJ^FU8/+JB66IBiE%<9EFHfR6Gf\=LrV=#[_[mE/9C/$47-WVd`;m2Ce-q=0M*]I_d7(ABu,0N9+;]P;@OWB^4S#7Z#a">nd2IWe^B-u)oa!61QhnGYpfL_-"T0SqBZ_-U(mY-+q?]%'i[>e)V`L'qKh_.u1W.or`*,mXn-n`.[3&)XQt^CEmXI`,VC3d:"nC3/=i]mE9W2/:Y9eLn0Q-e*Bo1)La^]6+HC4[&%eLWfa&[VQQTSh+#"n_Y&_NY"P@/;OkZG`fIQh*N0XgR1Xe,U=WX&qYZ/@PofIN\3^8Lu-/mFi:n;NpT8%cWT/(Bh**6;R/jhRk!l=ap)2RA6OP>^"E`)Rc@EK4,4=g-6I'naWn"\NG`\5Lpr<(!dr1F=&oKY=XIUM,P^NBn$'#U^-M%T)+g)CQ!@`92f:0q'#-bBJ:$,WB$['N2BCR?`NMki]QlN+^'f12H-'VVD;$iEH-j]<[;'9]W:4N=GCB,I;6CADKW870\:5%_fL@beNugGX'c5cH&-G6)H`&]6cp4]^*Fe,Gp[dSjpC'W!pJ7DFjiER:]kSlfV`$NUPD^51VCm%T"SZnK-RIY""!-+,F_d!XC?oETRT7d90+.d]!HQj63cmp`Q1O1bRk8C?e>^@'_r2!_g&Og^gdiidIf9,NABC"UlbC_o[FgMK8`9t-)d2"EXTQXUIM8,r'Eb<1M+_IYsX]Z^]4:[A7VKHMlg0j.QTVZU;($KHmtDQ>[AL:IRN0W8Fl]SF1I*a(85p=g4Vu`Y@#%6hM'?JBIRT[*'AIB>]Ie3&$IW3VUQ6jj)"r+brHOX'61[Y!Tb?F=Lr7c>p3G6'uq5mjmQod>7gr.LuNp`SqUYp3QGg(qE:^>`sf2]46[n)p^H9rnjKp'gW$99P<=FE,!S:ViLeWWNXX=U`KIR3V2qJ(+I(5PnV3cuomQ/KfM/(A_)'uY(L^k'WG+m1MOc;U&iC%1riB1Z/MqtKP,:Lr%X=^8Q,Q\EUWV1aMTI/3=V.5+r9OQ>4*(G7*MY>V2h:r9bakA&WP.S5gN%>cM8mLc9fPq#?bS8N_%]XY6SF)k)R&52o$29cb!:-^j_l@bO(h7\0%U%[9s@OR#Fma@qipu1r6gU!-teq($(=gM^b)lecHL5-!h:dq-KNHfRoIX[D7AP0g`I=-DV$9;\?PjdMEQRuEBbEbs0XI(7[+1Sl&o]aiXRb<"<03VUZ"of3+W'OGEaH;,#%KtHMK*<8%AAG@2F1GERM'unc/:;1CL6#bD9MQeiA]FIFG>eBq0kF^`]-V^&J=D$DU]-0DV[A=ZJda'rqPLanNR=S-BsXOTViQZPE'\Fb))bOjh'C3O??0i%OJk&Jt.r@:r@K8_k[75=gLRt$4=)Tn`.[ObV1Thb*=L%HMAIouIS?#2Sg8sD.;D7="CVX/.58?Pi>rQ48WtL\oZ*"7YNg7t=sZN9f_tiA1qIo"Y"Q[2i:Q9_B'Y.hf$Rc?ZZod)EpJ$p@1M;ToV_^g-f<:fWBfBn_`#`Sl$Wu0H<9bJg$-hak)No(ESK-h-RkCl8KP.7NA(NO]=FFgi-oMD0tJ,%WN/I*k?RN'JpYYJ#26J#B=;-VHcDiq$j&F$6fp=nE#Y\Lb:MTND\;as,/BKr>H"SRi8NXGUfjs37I^Hn-;^D.>,g=WNgs,4b[-o;l*$Z;aubbEjmAA.alDWpW:-1n?^P`Z(gmgU;dD(05+4P@WU#-K*314C[Z#=I.W0-jVCA7D0KqspG@`=3J/$'`;p"$[%OYl"a8%Ls:!oijOXhUU)U*L*d&e]6YlrdWJL(^g^4p_N%Lg+m]%F!o*-TjLr>U-L`:U=7sKJ[W(S9i-5&_3!QFtV?KYfn92K'\:>4iHMcM\[nsbA?:]R7tADqj&pi%NRV"m1BFT*6fB*ORu[D8'(i0qtho@8?k-KRPZa'2>m/rNugH_)p1c^*/=U=u5tS2+^KH(&3As3;;n!?i6rk(ucfkS1tbhTnRJ46jJtTF]0DX]OJj;/4nfl\EnYK6b.='P$ZC#cgBJrbuV&MY?o:S2BD()d@s(h]&<1mLPH,T(02CR"(+G-Q_#`0e^gj,3EFDCWDf^VN5geo,CUb0RP`N*[W:GfWHR[_7@4,^S6C#l!:?^>SuBceZ)X>lu9^)'P4_%jGlXMUB%MXfJ-3VX/dc.hFI!j:e,F/*$$'i!e:"7@FCrCH8Q3Hb!*KBn1/4]lV]BWk02hB8?SZQ!=d!rGe:r2(D.o,KrWW*ioB(0f^VQH(`8(lLqBfaH4amUJ,YCOG7j&o\MIY$n)(mH]U!6("iH*+k;rYT0;^os51E0_V(GcO*;mK6+'VC<<8YH?c^m9]Hc)^OO[?0#/\Ha-J1%q5WZ8m+)S$E7Rl>7TT&acsBj"hj`UKJ/h6@,M&RH0sPGjutfPEmk/St^Xp]9%2#DsE2Z8a_'7+XA<9dDFOuF"*(&@kcU==;rC68i?rH/5ZGK]o8J7iB@Zh#8[_5mc;/0/g*>AhGt+S9Rt?'<`[.e"1E%!P.(0<"6(.r3G^3=ONKIug;#D8-m=&mE9brPidW"/E.GCj5G3q.@+:H.:iLi54!=4fo:mqH[BXi<;TT+L%LsgZ!==?oTFY42F,Q!96r#=(NZ:X)Gq4.A$SiQpJAcuB$2X;YA%'O)L]mJmfK)<"2Jh"g0"eKP1US=;0k84"h`QL9*_C5Eo&\k\P5Fd5K3+QfKmao-:6C=bMesd,h7Hao26L<$:7/n`.p'6f^O]S@6VGUBoB&be8E^6e)LV>LJ`K8TYmJ&NJ)@M@LV@WC%8TbqZaE8=''pH%_,IbdO>Zk&,?X=0uij[foX&>dOpb,h.EP$;TN[^hQaaf`MZNPcb[M\=F0cP0:GDD>)6O#mG5Sb_O[VXrd/+6l`ig;#b(0.KGDr3au'#&_e%S?9=TgRghNZC3I0ae"E82N=P`*AajPiib>-s)>"g`[W%Htm"0Ai^*UL5OcGOJjKAE;q"T7m`NOH:%D@floDcuO[7&"oM`gt.45Kdf6F>?:OqqL8;5$&OITF(EFXam=n8)n4RTRo\>68`=*8kcn3l>[]92DQ87Y^KnEm@F%@B(+dD[/g5Z?p,2.@&iX.&l*L'0cqqi]kh!![@1"^dn45\H/;tH&`lH+iiM6RA'(PRm;PiA0*0c8;M\ED.FmG@1A%3ESJHH.kIJY@:B>irrhnQqZL;Ma_;j\lp$t;ifm-H;!(oWXS'3Z#>bhGZRA1,!]G(\e(nr<#VQ%nPP"2#&Y8(&MDffCimI/M,_XBbmeD5)+q\6fs>=PfnR?k+7:c,pi?6'BlRi5k,INjf>mer5/`@/5V;N25[R-Vp=idii_X_9RfH+68.]0!K3GZ3@+"\RB+9R!#G5h28j#HLtk[qLerA<*[AF/G/^U^\u1#<[>6q$+TqpBoCMp(+r!_fU"6uT"=bmRl86H4F6biNBCfoL;&K%@=m;1%";d-5SXA+%O>DbEH#?@@otZiJ=$[d5meiiQA._4\T.iV8.aTCKn&skBlJ#Fr:eU67m^/e:i5pngUD@ng'JE>^cI9AHEp]o*$!2ZGIVYQ#4`PQD)gp5mLU1TrVH3H?Wf^rRlGZ^+F?,BooN_Sl\F8$Lr@6M+:dT!!%CR2/3\Q\:7[h"G)sqmR57@=RcI3Gn3&o:EeY&EqWcT]p3uAZXd_:Q,RUG5"9o(-8Ws@Xi/&*pW"XjQki9^Ec_!GRY@a+SenG.XWhs3A!Y<)0-f`Im&ru9eD7fbpUDK/CH#9"a[Qa-9$$@"R%>G;I,;M]OTuFr5SbtY]Zi$b;3gPq(=f?b`^I\)+iI)\sQu2`Yk`!/d[gNkg/ErJ+I%o&Ro?-UqFS-p$kafe_a$`5]eD99r9Lb4tMe3OTY13HF0l(JI_pANUD=R,(]hY+Z8Nm?.kM'5B!9X+(rok/cNql;59L^jQA6>hoZ9?/R"Am01i3PM^.BlVGNsQjMhTkHM#RYD7S,k8J?Uber4-1*A3rIE9>E7LZe@*nRF0AqB9u2/Z).*.cU%9;#9%]H#r5u-(%[DhdSVH3L[VcEqAEfj=M,T"EpHWo&e1I/ruNB-GFiQ%`PY<;TOqC"8iaf/7D>(-oB+&ib,[N[0K"uZ(0A)$>Mcll/9QU'-J9B,11c>RVNS)t8OPKa[kVpZF[:u,ol(,68G+dAC+aBWhY)2E#D4X?'a#=9h<8O'ens__$$qi/K@?S55gWj9?d7oef'G_!+Em+)3W7pY$F,4+/-ci8#8hCo^Qm\btbQTaTr95n&[4i^ANacO:d@3]VeMqd\qaEcC[e-$pTX?QlP=PZa?fgbFc_Xqni-M6jY+!4^"s'*fB83rceTM_rr_YB4^ot"J]m<[YCE,H]ODjM3JOND/$n"iB`*WPec%<5.n_=&_*b/-s1]6>(k]j86nW_s%h&3:3K;D(/=j=i[Ia_be'\@>?n)(e-?6#s@UGAO"EKD1flCP!OAOXh0Z&Gq0ik!]h?"N!`s0&)0-M%L<'amC:`G3sV;aq`%k*DoHiqDL'$9M>jmcHDP-CRX:gA&h]k\X4'[;NR82j7`*3gUGeoL+L&Y=05X`_QDirV+R_eHcq^,3L1XLp^f'7#iJd\fNSm9mG#*g,N]6\AC$j<0OHId0?Fpjc_&Nc,I>1-0k/',\LN]Q_AG4L*1',."7qo)`ESH-2_qc27787V2HH)X$$qA@UHmc6p$:TBVG<\^BDI\LN?()]lPuVpFmIVT)smnkEo\@R3$s<;7(@=$%`_1YhnC,WK%t1'_C'jF%Y+qk(*e\9qsV:s?ZAkuF>r4@#RLgj]QnRP$5M(!J;GUIRZM/0-cV2c2+frsCW`>6[VXV`P/t+Nhg5"_8_m"%J7>[Db7X\=Jj9WUYs5E(T_i*/Gd18L<2^@bgYOf'f&6#BS2leV$'aLn<1#Vc;fH_rTr@jH(GFDK%tIQ.UqCm<>19[b-W8=%\E&PZ*?@l%#^5M#ddb41JYl/2Ed%Q_ji\GObS1C[(fLhgC>??;$h+1[a4Re?@#2rCn6"ki\h^MZ?+FuE/h.`jVl-H^(4M[6`/p5l\./J36\kuRMM_J;,Zh-RaA:j9NRP_(?.,:IDU*t*.i!0ecCLHcLfl@#GD-A=.%Gr8qiE-qHp>L5",-aZ":<_SQ3@X3W%Bn;^6s]q2N8V4$@.1!21bSpk>O=Vn`.[?Ad;6G@Wa#0n`%NHqDe-9Ue-aab+(J5jsNrrOa_J-DdLf-82a[Wq?#f!Qkqt@;%N/?W;P@(nCM5!%3`JPB\<7SQf_1Gi,8SjWsEofpT2+#sh@GF#%N/X"50lcR40bAdZGgP(VX6JInD%KG3jJEj@R]r`O[a:L!Q>R"4\%S;'Q8l6cg>:h7JFFk26WjkokMU%dPA19Lq\[ndGdme2\^l$#p6ge]lA+l-lPF[kH=7>GmR!Pq#d!h^&-r@"c>dOY^WFK`j]k+ggH`MXWC>>.&+1%L8P.,BqU,!O7'/Fs*2*=Kk']d[$'u4[TE.Uo?,:_;.(R#=.,T^]h,]VhZ?qtBF%-K=%E67A4P^0J6kBeE+GkJ=sfJC^T:G-1#*0GAIX$l4aTGo!>u4)&FnR)njpf5JVCL=^OA`)K(1,M4897a1q*906tB0I3WjTHO.er7%3oG-&Zb#;OJm2i$78rqs=t*^XCJ,k\E+#p>"bmlL$N94^#SK2hs>1OJh3=S7Of0+Q,gXJ,@]p+9LWm*_^+*m>;tDR@iYjFdg9`3G'3Sec0=2q=lEbstVEDnu@p0FIl:tFq7T_b)CQ5*'4=1^U%TKu#3^s5_P6X#,p>pf*"4X2qqXeJ*1PW&<]Ahffm`cKfT0L).-KTV\3aB49KeVE"^d)oNp7T3-\8[";5G`;,.9[MC.4TK!EHE;fX8$ec;I>Keg6i6LYgc%\Yg,K5W9OY[cP1jngKe?j2[54XWimiOfHQi04-p2AO,#aRJni<,KsYNWMqXr!XTiB+XSP57ZA>-PC3ErZ=M(/]WSI@JF>Kp#JSS\Zds!SC$&A_SjC]BQr]lBE\oK"Q?pTaVNp]`R06&ofirBPE";1K?oiYQo3hDtT7rW9$?25_,k<&@-303rL))3BK<<;&=eX7>hWn1;q)J"8!V$dT%<2j$Q6Y&3Sn8l%qMuBBT`PSTYI:^l0-e-qaBsVc7a'eh))ipSh)hNZ:'"m+AQq/hV5.c<\26]pG);Pq,p$l(G7F!F`0HeZ/!/8t.`@Ub.6W6aFb%4aV@?oIO,l9LRl>8S9a?@=ABC"6C?cBU7`_ElR$`\6YN]Qdn3\[/3\TF_f@0*h7u%h&5Bl9uq"ad_,1fpF5[k;W.GgTCK:,J7a>VIn`&UE4Z,HW/u8F(n$1`/P]p2K.F\X#V469-_^Fa&$O0OR/4/mVkA>dS1l_1N!3-Osm0m)&?JC!/O)'C%3\;n@#29!a@Q9X\`fXEleIH,*Fci]m<-(aD',#V(bEXHW*_T$M_STmF\g^QeCq3d)=!.[8j-#2cT?h(RTsSNElETkrDf8.*!<^Vq:]7OXn2_^bBEe#1:.a9N4s:k[?orr%2I?G/0F\Sfei[/aB1Y$QPQoT=JnX`5SZ#B,MFpA[Ap+'B(eU;r<:_g:;+km9qP4*N;:31.Rp#^IZ$3;,afq[dL6*#Uk`Yc8;SK&#a*=P9`TX/9)UPbAB&KR5AWPOVhL^qkX.OVA]lCoFcf3*LPV^k'f@^,qDZi*-:d%YjN5`J^:XSSQi[NC93$d\Vl%o"tO)&9X>";GLZW[Wb3P/C:[NZC4H=X-C0pY\=0[WGYO33mUIFC`K!\SF*Mp2"&8+9]E,4WQ-uEQ/1O5d;*#HM-Q@Fl19cN`E,fmFV:eg%Fm;rC_Lls(h6eTL,;q/lnq&$4h%UkaG3i+5./e3e;/e?c'oBtRL:g8e@KtW'>jMVP%k9GjZ>R=+LS=)a.S_:+h-D1*t`W`1D7-7hbMun('iu1Zb]e/N=8D?kY"^:Niku3cA.PPAP%.ZikIf9-&G;ZLk!`;flN3u[oKf9"fq#0sE8M"]Jdu\D!ZE](m]lE':?5O$!qb['H))LR+<(u4^W)-VKDM"7[paudZEH,tDf=O:1;b.&0?00[6SN=_faL?*Fmb+r0YJ:(2m\;!sNj'3_]Lm2TG=W"C!2F&DN$2%l&Drs<<)=(=DMYA3d%KRISNCoTbUHJf9UIMBo]X]?L(+4cYA`=4h7In"e>ZC$[Va8M_3!Ff@.s\R46KkXDOoKL5hOYa+ZU\=p&ecIKaJPObt_&AdsQ_d.9a*Wfa>0&eOhim9:%7[]WThccihR8TQF/4;M@b&a^&p1ADtCZ69;f+ojULJ)UK_=ZicC@=Yd>X#8-'^7?1rW;56Unl>Fj?SiiFSXmf'Lr;#rj-[Xjk$,"'RPS)_\#BQS\l-b05eG&FhX,9/1!V_"k4WuO9Yd_)#lN188!D`+?]d[hms7kj-'r3V%0$'/"8+l/t5u2K@Ee9JPq<+B[cQAfZWDY:6D8lLm/.rbRgriO'DV_a=h-u:#D^9V(S<^/k/if7$EilIr7o3.[m:iU9UY%nHM-R.UdIYD4F'K;UfkI9GOF5uAcpD^'HR@U=IcI((D1'/ZtUf9[riNN5#%S/'hPW!N>fI@5]T5Wcm91i'A+W3!EJG:PYVXfSD(AdbLHtgfiP@`OX'uH?`mYEOOn-jS4OOX)F"e?qq7#QnA)%ii@2alcOWU,`AB;#/Bj@(W`?*ue"MD59O>G\fkaQY5C[S.^-+ReWk-tAaE1t_77;o],?=lRIfN&[mf*1^]Xe*_!$5[.E!n9Z3r8R;gE=:^K)FQCK80sZJi`r(ku1\h5g=tF_h8[E*Y(!+gb".(M49tRYMRYK"db),5"T,c5pC<-))I""-oku2V+[.E9!W!L')#7?`4PfG=gM4.CY?"i.B3"+f/&_P*(co"8]Xt)BGlM3m`=OCA^EC\Y!0Oh4@W0"6@5@_+BqVbWe8#7o7n."pj4FCm,O\ohdq?XI-aqsN9%UlI!M6:%%Q-e5kTF1O^\[1M35;"0IR[&Gb>>%)`JO6PJu;nO5\1D!eLsea-^_f;OB7QNYYnC.=_3hpopYYJ,Xh$Rars-G'7J91!>_(71,hg=0>fUZN)ZuY?SJ2aLXp),0,]aU[Z8s#SL^J;56T3WSmmEFGO9qEh1[>X4mbZ3-_hJ7fibpjh9.F=VYP0g(#)^MU\R5-K$GBiW8JM->)/_KL1&:r#k0-`>8GjqAt"UGVLs7=Q$+lBG.]*8B@BUp/-4t59;R(t#QiPUFl/?L0CM[7@"DP.Mt;[0@f=3Bm.r`lQ9d"Q]3gc8rg'IP7Ur">V.&:R.g7++lSTgOUBlN519N\cN9V$J)9Ukci!"jBROp>pX32F0"_5PZp/a]g!8U@f*g:!A99fHQT9-LW;C&+O!-lFLhe9GJ-u_moCMQ8E8\OKKaYM8lR(8POIY4e+j[/fWM3Pes"BOYps]o.aY/>o%>8MU2TiXUmuY4](pl>j6+HokB9%h*M+B"3h7Ak429Fc*>Wb/!TR=!Cf3a"^hT$FbRj([!Fju"u%j+\t\5i`[K=kCJbaC83qDql9PoPl>%OmQ5!Ze9J9pJ,K#mgnM?fb%K//^qsE[qCZ8&bNHpsn4!qtK\3W[%ou^>-\XhS"8oe"8gP3oBQI_*nE0KSr^"j`$>omKH.o_OjVs_J,fMhfRUa+.]Oc(^Vl]'*rU7N$iWW/$A@ua31?F6?:nU(Shn/kqt99qVtDWscLsoDJGEj>b*Ai-<2icLg*/k/K'r9d\TTA>*ojm8,Z1X:5#g?I%_6(<2`N\2H-JHfsY`:-od805DGF/5<.#u9=0JLl&2-$6pq<(:j,&jS*<&TXG-Vp?'.]jsjRl86@jm1O%H)6Sg&ZKftW]sXmB'&c,CB]*0T^_[BgK3rI(3a9k"q89\UiVj=::"QWnA9j3K^d5TYj/T$//;Z`)A(F%7lh+i%^m5*S1bsJHs"+13RXhGNur"+'+\,:m5L(;aUN4N!t,\3JqATe]tI]V>T=b)`I<>9VG(-c5QM_S*BJ9Z0k(8p2nN\H)GTP7%Y!Ng$5kd?S5@qMF6DPt;B*QG3ctd*c%9Q[aK6We`lJNIA&jVkha9H!arcGY3ICJ$h9VkQB@!/P\h'BIrr%1SAE8^h2\$feY\ViC0/'LbB?p;Jq)s6,*7iA1T0@]%qA!VfGOOAl#6u>7I!F/>;401NP3c+Y8*D4Kc7Vk2i4snKl6qE:7'@G!,9IHu?!U_B_[#5;]:)cR$[;'rV5p/Y*'JVt<8\cYFs+Pk3,sPEifZ*@NugHo[4E%h;nQ(gc;"s,B?mSM-g2Udg%NCYr9V-q,k)YGZYV@=0A7+6&lZn8otY@#'Dp?gUg$Pt)O(.NChAY9ea$G7+*T,RV(qjW&2YVR)b=dn7]\<%`AkRq-P0&cMc-NZsB*bKH4puDB(g5&NMmYF$ll:1dNq5qg,M2BQN5O72F@VXGn"k05\76j\*;]H_q>Iecc4#PuD,Rn#Mk09q<+ke-->]Yf@1M.&*Z:0Ze`KNH+k)AO*8TQb)5])=L,f@fl0C>->a\,Kh3lSHVC:P_&)FJF6=fu%EpV>RpF2c*`K)H,s1l/h[\3EXflDs>6,;rd`!M`2N`K!O/0^CW?k0066SWu9\DAX`^?Vk;m-a7<<7Q>bgX@=Z)N3ZNcqtKR6ES@u\frJn4@0Cf)/q=pLREfL@U/@a(3Hja+?$0PTQi!b!gU9=qqMgWlJG&U.7>`gFnmp4Qlron>c#`r-'?68Z"263-4sP[$)[m%6+$Zo.WtpQ(e4Z,\an;NM*$]/CY8pdOWj?;2[LeDSV/R+m.r!.uJ,ZED.ZfR;qs?=KslHH(_mbhdo>/7FX8-VcQGe\f<&8t[k8#<(8!O(?;6,C\_UQMM>-;c9Dn+/#nnT-+DfuBKM[FFXAGSl?ChWI3`)_gETHh$`==B.d(FXF,`?No[YZ)Nr:mPM+TVY$fm&GKp@cW>nF^1*F-rJ6Rj;3Ei0T2:-q$1+GO?WEPNi?'Kj#"_N>jh9eJ*E-Yr%\)$cFigSTQS0Ek<43#S+Fc1Kl(#!t=#Haci3C<>_dWO!!iF[kD#%@Uio+'e>"TZ>.pieo-SFb_d,c,hns[_(5(RjN3Sjq$'.#;]ZI]G3sn%)""guhr.Zd>K#T[K_l@QS1Ss4U.(>[-h3Q6]1NKY0"=+'_Mm:uA?[WLS.rl'3C*HB@1e<8nm+KjhPbm05,XB*!lXFiZY6Ln!S!KnEn6GD=^[L1A,0[;qLB(oh7W58(V,Yuhr:og!].[L'&HBFkq=8e,+;i2-&gMGJ]W"i-:,4U<-j>cC%rgsl3A+Hjh>-d1f2(t*SND$fQ3#JuP6@1NDDBab[_Zg9k_:V(T4"gUD)qXeCH*)KZ#.jrbM.I>drtfL4iDPnh^h3HCpTI]A?Q#D07qVPupX?H=!_aWZZ[,i1C1=gFi6qX*%Hk8o%FdQOeicfgQa/20nJI(Z85(d!1Y4=24DmYaQ1"VYAD&YGp'11\H+&o[6q]bO#dc'pZ&<5`qlCMI&>>t?#QD;W'5q(51I&ut0P]t7P/+<]??Z14hsfI]Zg\@K.Q\i(O).rq"`"@4kWcCD`n$Pb-:RJ?[Rn&\l(P-Al^506]6cC>at3fY(\$.+4^:i9aP`30c#:af!d_Y9(@Git/F9a$+YC?=Db'=*q$bb%,We/B7MX,)B6!E`S@?==@SVdLbmXD9`MohCl3@;I"d>Ib*C%*T?<$Pt.n[J7[+\9Vi`o8^0.jb+d9Fm;rJ,(W@"SY"!6!'11qXY%>;_91Ne4)`ugb+CIF"i36[47c,Sm"r@\PPf@6rME#G5YRV%AVs_aP/`n(3H*fh`@nTeGkgd%G$,2U`5KSbrn=2A(NE#/4ZuM(PpoX$Y/&i]:>-n$1ODi%d0`FI,8D_0<&dZ1\Q^GWDr8:O_R&`#gQ5>q"[LnH>.(B1p&XI.WUo,g$ZS4GhRntmLt\t82sZE@-jR:5A,P/R4*P]uc^d.AjN[f,+!2Tm3EeX$ND##?'bJ^JHl4bSOMW3lY$F+f)8t8D+Q=l0U/.CFBiJ7TU2f55V?RWMDJG.B64l`HrXl\"JrM5WR7J2=/o4kr5\0WZblj%7-".7jbr'l$`A4;hR7*EE;]M$s0'--NiV1'r]__VC=H>u2%bfo)Ja/o5LESBMdhO;@Q+llX;F3t@Z)FfU=`*i#e$Z;=:j_!:f0Li6pRRBhKs\bn*dgEqeWlkp[7J9hL"+/4KglQGP3i!1[!!KcCDeLWsHD&[\0:D+gj&qj#X^_M^?I<%N@r)Zi'bLE@dK6"5o9WE]91)c=?hea+uLFGO86B3*T!COMD--Y&&ZiR;b.+9t$3I(%dI+sr?:b+8uP'm9,\X7]_N#AD#04@p0R[;GOeB`go!Q#WX0m@sgHVV%)Hi*O(FRLg]H1+JS'J;!j/iGUG5!C$UI?l%2O?Y36]68#q"(`V!(I7%"coQt+@9/R=9nX"8,;8cYh95;H2Jq.ng86aHb(uR?pue9!VNWC&4X\*4LcNKEJQj8bhnMt]J?5iRGhbB9eiq54A_XY1,@BBhj(%T9Lq%I.4Zi6/b*=JYWa:>SI!0ZkRc#ngGVFCB1-sJ46iic/)*Gp:68KJq(RM^UlS@8@f%(V\%N2[rNffS<6&+AN#N8nf?)W%$rrtXjRPelXCm-o&l;+ZJ>>*BU,mRmn8CQ4C:?_d+"+:n(!B)2V301,C`Rm-L*X1jJLtSS;(IT^97i9V+@,3B:5=%=S*FH27"Wi?'j21?^!_4di#T&DBX:)\a*%d6X1k=ipEqIt.+Sd:^dsZ$_%T4@NL[*$Ig;mFnu4Ec*?ZOEduq[:jhJ;ZS&*\?%D?11I2]2@$!R=7PkP;Vd[+a1ZioGc[%1;H-UPA&\r>QJB&oX)LY/.5tFTH[F4ud=KiZp(6dDBU$/-+L8>[Nu^)K:SPR_otF"F`lW-27G\BKQ*90T(s!:Aa3o#g9bRh[KL-H6:+"TD/J%:DpP^PdB#gOhq.@LSekt8?ip6!m:4dt_\^H+W?WpVO)]S,*k-emH)V+;2Cd>$3=asS,bXlS)@J&NuH%qo[PCkP`b:>qMV-P%7\+?X5tW'mY"7Le4h-kK+QBJ>+feWc\Tq?a:aFC6JNoKhfTe#,uWoQ2W8/:rM,[G9:dI/%['_I9dh5GU)iLbi\hi"h"I1gO0GTLXf0Vur,k2_fe'lI2YllGYg[Ep!)_gDZJ)!bf.0mdAB\.7Jb5BTf.a4:[c.;l7(7\>6%#CO3UmW[c-m.3g2()jH>WLI#J_+UfeO'\'-_CY?")GOOB'3nQ+$Jb&C&)`MXkDr+`YgRtHos8LU#f"Sl4aiVYhYG^12gaIY#hsbqS6CG5OIpVN:aZ2BPH!k#&DI!<1%V\R[m$A\@867kWAbb9D_h[^<^E)W(MTnUY[5;dVGim5[:W8hbFQtM%_7Uf+gNN=0Es[beSc3EU+5W2"sHq%>4DY.E7Dj^N]/'#7hm>c^A6__N@?L*`668f[GNm9jX4sflQrX@7$I)4`VI&SXk2jb*;u0#4Un=rXW:_l-5gTgg&!fqIJ@A]TP$aH]K42FR4r$H0a1J-Vn]>!dFp;rIfiW9:%8*Sig.K&#-Ogl'0O8@7E4<46'?HLr%2s-OGk5p$:5jbKcV<6e>?7o]`,DY(TV5-RU:sM?!ZC%OEtip$UYJk2tg.>.)f.M8891IJ``c23+KlpB&3/0d5!t`A?'gRAYpV[tSW*k/J<,Q`$99cWcCI$s0A+!e]BWbFTuPmDh+.'4iANXK8MNUIWdUX^fD3nWiTI+QsHjg"=r=08@hFq>b)nd)4I5;5dH4_AH,J%n4?C\H?fi$hMgTOnp7]F%'ZY"^erV)3d0CIW+K,R>o3kg%>p(o>d^b$E8&Aj?1"j1b8H9t(j#2P))InE:(+oJ++SK2Ui!$3Q#MJ=hL_O5:rr30kfd\9/<\rLE4@Nso0DZ^4SUf1%1e>ZAH^E3Kf"Jle%p%?;+92nB>(dZjHQ.p5'o]W"Fn)UfeJGq6@hE4+h=h&FEnup?acDl@$%M!)!Wj8pNoB+:+[WglXR?9'[PZ8?E6qp$8NgL2]u@d*N?!?iViuhRk$+(1m'-=0Gr0rqi9MHdii+q!hj+o@p0=T7DFlWI6:BrVEo?[m<@'CFaokPe48>hnG(SQUh[B4C*_4.riF5iII1We%9gB6@U[D0i@k*&2RtonDS0j7)P+VfU^7Vj2WHg3&)R"TgOSFC1SoH'.#[GAJFI"2fI^,,mFbq6cc6X$*d;LVjfm1n*a'?1PuXQjS7'fMgb6]&K=Y2Eo]c%N=-(#"KS.!T_4GBUE^`2LeF'eiRSD+c`LE\aNn$c<[*_S9qq">?+P,$DbVL1"@qj675H%i#eR;T9V"6;+0+s_)P&''0/'6HVb*ai[r1p5p7\1Rj9$hTKBi6ufeZi:gPHRk,$!I2GFpm:-M^c&d_tnod#O'/SAYaOe%Ko^/;t2^Idc'3)Mr^HC'bs/$Gf:h%I<'?`1;YSJM1W<]lRlJSeD&^sGqgK-X!s8p498O/:jlJoi(f-\`7JEi'4*IQ/#m[I%)9O?U7Rfi^'buCObg4VuG)OG_aRS<2X7m\]Q7lUJr6UK4_Cd\L$lbc=R=a#,PatX[o4:<[8(3I3JHH-4r%L;u?M3(N*qRJXg65cCO3S)k4$[QS)QA?N8\kT8B4DQ`.'iY,J9I.krQZV3-+(N(2i2?[VacbQ^>af$p#g2XWd]8TDs^dG0r*fs1e7&-`g"TL"50rVQWcb:e$^G4+ed;,L22$'@NA8V)E=gJj8YnF5pT#jSALO$EV79M?-k7T`dFW)9>RDOllN+OGN;/;/b41A!EigB@aijiWj1jcebtU&hXp!FiG;"#+G4"!0NfqoA<7T8c8"2DRp@$l\'GQ3A;b9Q;2N'l.U5Y%i4ETd`_hJU+o#H_M3=m=.N]`S9geNW_9gQugpqLc]TCMTo"bk=6\c-d;\'f)$Pk;Od),"_9q!mF3GpW/1Fjt+CMW6aqtA^tgE1afJHH/Nm+J^^gU?!hs*a=j\O2)[q;?l9fTZf:%X!a.r;9>TrKQ_i:RNsA[m35%a)Y8CdA'4#(5PGDo&kN&rO3?,jTY4NkKfc5DmD@/G3rHiJ&Yc",*[AA<"V>c:0:V#p[6j+GTt?k4$/@*EBm@I8FP'-'A_[i4F")*DTX/9UJlkNV?>A$<4-Mnf&m,[a?2LC3:LX+=Kll0:8ofFRD3a^`5H%\jlu%*aX<^:p0:S]h7GW-Tj9q7TS3U+'48=mWE`=`CW,2LLDfqKAM,m,W.m=\X.[M5q"aaUBQc4d_\,j,Quac6S7!'M1rJkVoc5_oJ8!9*F6Cj*hVPd-$OFd[J,Mh1d'moKMHcVom+]"1TrYA&]2m,G=0Gr4.&qapqJtJnW[VU5[VXVPQ<"0kJ'H6_'fk`GPEQ@]$7[MT#g506U-\f#(Ddl!&9.-s_6ILjZ74JTdZXQh#baPMP>:;%5Q6ICh*9TGg$\:rW7quKj7(%G_1POR3!$XqF;9PSI5>KZ^o^?CQui3W=gCHm>Gqb?E-6ruY^JfH:]ifT@cS;fZ%15UjE%LrtS]67bq;6slZV"<;n+a0U0XD:sA=]SQ=C-(G/Oo'3CG!:9H/99Y!f%*l&#-o4jQ5LRX]q-cH0X9VD`ALSABjEfWdf"qbEY@;,P'W[LD]OVG3QDg=G-;?3C;-a""b\-)e;2+G1Q=ib6oE)5TGRX'i<19h@peFmBed&"8Yka,WaS9+[a,d-Yh1gpdrC:6"&ag_MJF:s/\)_[fUcV5:"'(De"l3tgmbK)B975r0MXK0(#GWab(DhhhNbg]DTD1:<]Y#49/m.uR/khm$STE40!+6,pZ5Pn#=Pl9IT?.OlphSSd8uICOE>"Si3k7n9t^%r_FK?XM^JIesSL!8aE>k:9o5"9\k32iL@`%NW^(+$g(1?(]j'fO-fWR[fnlHkLVPW)8<[*=<;fV\=pdSM$[Bf;Rh56[40q@'\\60iMn+1=V]Xri/kO\i$kIJ`$T"m?l2B$DM1+5ESI!%m'X^7\:+o%!:@Rb1Os2>Ydr7>i"S`R:SU,9nGTL,q1L4TPI6AAmnaQ04rV[I]mTg?(2="5^N$b%`RGR_;]co$[NO#NH4[&&$_Os2IeF'DuMi1NH-1gm*(V0tLq=tFrSHArrKbbdN2f@CnYJ66UN:c-5U3/M;+15n9B&trM(L>8tO-,fs(l]TQS2kXm/hYM'?GCsfaH7^$Y(D9#pisCJK+8A$ib76jo$3XpP:#6("m?6$Dr7E305o^[_(CY4P*-G0;g%D+?4V%3NfM]S&JPurC/ho,nH>*'N=5Qr#ZVja<<][T!8@&2fe^2o0$Qqn8P)J^&RsF7n(p4_'jFY*6#NPEWo`d@c1=DS9ksG3p2Ns3RH,AJ^_ur94kiY63LoS8I6?\T>7arX2nILP1=77q&74b/t(e*P/c!#-^m0!33'!fKUM;[d4>e9MEZ#++6PU6DmSLj;$)SN@$t,bg"CPMZRE\7RdU0E\,9e@2JcLmp?e>-D;)L>@m`W$?G1YZSN:oZeucE!h+C4/&E+Q_&jmPe8k*/'VG3OL&C5\o)*ir`$O^b#Wg2;cNOkN;kAsMh9he>N`dIC?c'70B1h+q2:#t+oF=.k5,`mmS-W-br;N'8*0'XKoU7\E:*/t5.$EmdL9"q]G>`g"6'Dh);RZYeGT[1@0+XB>rXTP7*OY$JI%)lHH%'(c?/DJnlq#nmS'h6h$b`(s]E\8["lg!.bN[jXMiPa@^I*BKF1\0:Gr7%hN)Z8)q$O0N38C2",*6#.@(OaeeRq'/qA=M]?LJUcOs0IO@'J,oaOs"F!CC?AL(lnL=R'KRfOq:4%Thg?(M&gHO6[=R,A0Ui+\5Vou#;l25Z[&6]lnp]K'['Yf32tCD_#RhY1bhLlVUYMhj.7]M=jh9Z(JuM\H&mG20n%XACjGEGk*:l2AiPUHBfOok$OFl'PVP^6Oq^u6i*4_H@YVeYke&de$)1JX6@2"sng9jT;.RurtNYjL&6%cGIECNEPcna,1iSd'6L0QWS;1M&CLhD"YS.f0qW#[VV@H;\'a$K]N`l]UdqdUqk^<>1!*qLl$sk[r*30'?Zt6K+8k\nG;fn&Ho&ombPL.Q>,*^/T+F9'LC2.[*YHb:nN10)-SfbGWW997q5'dOoG%*?Z4`0dF[!:a%Qa"jlLTnHhZqK?ZuMV&/&*!"mCH4o--iDX]r7?bu2#g?/2.S.H9FL6oU?lU#ssZ+G[pJpD4iS[VS79UP+:'NP9LJ"J%cjIf6iCG6AIC5s_NQbqd]]=rqG.IlohUcsedb0G(?jeR"3s-N[@Ql;5J$_^u4W*0leSFG"8VW)[#f[uS^eg;^j6Ji[hQ1'jP?;oBnrTjWse*Y;T6hsok\@D=PM%e)LbNO&Y&3)X/OP9oI-pVh"jZtRX29s85B^nW'FJ+$=e0md<+Lo:`%Y`l5o.aH.Qu$FXWq@dMaPQBmhLc^kRO#`+=oaiVX:o4-.-*BOs-fZ3jCZY,=g?&5_](+lm2<[I.e[F:P!c2l(mJ6N^13I:Gf:$sBe(+nP?0'VWbc'gN=BWtFPY:<-],2S*1LPm9?BTQ6DBK_.mS=&2dP^tYoc=+#bZSh#7NupS5(IHE*=TPpV((RL:BYQdXj5YHJQ/Tq>K=Bo&WM&UDpbMIJ`^mf^Sb1lgq'4NhiHr3W\!ED\k]id-TZ)?gY1u=0EZKO5.L"+%u6H1G^h_!Hf?If/)S=+:o>*7p/AtC204rD('lXjfG#)@U`e5BSoQU3oLhX8.3T(E;\j9+@f0L@r6(bggO2];aYaH)WNpeUP%N0D2T/]6kCIh%*a]4\T4OU[lb7b8^EtkH)d1Spu\&a#Yd$^_?AYg!,4`ZkCZU#aqKcBaN2Gl2fBa$I!G,:]rnN@PiiSk&e`\@,!c89LT22OO+$cYGC3G_T%^SfdqL3`0,I-25bOAGTgg7rN,WubQXHBmNPb-c=')/n'6@eRr;HBIbiPMC5CWNTndf:D09KTik8Wa5B?d:^\&Ml#9H!P5jfm604%Ua:f1)@r\'g&eHUa^DL$MQFMI\>\)0SfR"#tD3=6ej#7]8%1!4F%1R1/[Om+>ck>Km!f;bjF?d.?[2#TNaMCN7#b;,p"R=L9USs*KV^H@6;J4+7-)saJSA:(]^tID/h"`+o%R=FabaIO@Z?GV=[a'C:CY#Rq?s+jPr:.4?SeF9(*R`.0HSd\B^8>f4RPTA]9[;3;6#g;PcY:4h4R@+q1Bn58PM!mX,ET>&/Nuj:@N^b7!\R?QX#Pu4(hS!uRFs]^M:bm+S9_KDVI=6P.b456#(T]@j#BC^d"hf6T&k@I?5g(cA41fRsc8djDS32'09i,\CD"d8NL]/SB+FqKP!C]FGM\e$1Gjlh_"nIT:`+IuFKt-4M#^R%(I../JkEl([6pMm9l)i)"kg>%Ek4$O9b#bcQ+`"E,lddXl[\3YFrqq%-6%MLgkR9H1fs>=]C8ir>Y@"1A^jB$V9_c-!b4tMe2*-4Q8SDe9_>B$=]Ef:/mbPK*Wr2+ZTAnEG'\1aaF5^juUI#`otG]Yqb,*'Sc&d*Rm0/8*;#j]o+.?R$5d2V8LGI!g=+op*$dc7mHX,a,;HO="[UBmomP-$PitM\fk`=EOE3BtBleg)5lKVbU(rE,fk07t?h\Mi/f-i1Pum^l1&FY4OYJX);%^cHaE]LOV3ufK_C`eui;:>9+ggcm8Y0M%c2@Q00FlnpQ'QGtVje[:mi.3ihUlXLUPU_]RNZ+15Y#kNt[/CV@o#Di%-j8jBAGC#r[a>Pq\om=2G/FC^:nl0N7n0lDLUOY"PQDtHO=HZdR11&k:i2i&:S4rjXn#DuN'`GXLPIB:hnOX_[h_0\^3r*!LbjSMl$s1F[r*3lIhqFET8eg>V19phSqnUV/s'RfZ?ZV2B"#kJPEM(sd)c[8='&IXMpYEkH)1X"@54O5N\3EN8'-;a#8fSEX]r8R$NpHi0H=@1D/1Fb!;qq?&90PJLsj^L67Xd\6TfDMLuK=0>7aXV5:Aj4a\b&!\ehd^jKd;:!%8^HFt?qV(+j,@ANCkYKnY6?aH.!e,GM'4VK>lhY6bXI'iQ8_FR7YB+oA205r17XXJ6?])3?pILCU0HhP0*ZNK&p/(hLs]2b-e(cIn5"Pn"fqW4#TCE%q*V[r:/]s"sPjhVPtfkK^S;E$RG(qMp=W,+B;rZm!"E@/$]Qis5[;fBZDG>9fLCP>&r,qu7oiOUs:K1:m]mB?jX5F%HW\jr8>oNhF!G.?:N(sLA(IX'QBkaQ6_PGD?.8s2ML)f^VRr?#IJ@);5*uNQBjFHgc4H!4+6sIGU3a](p-uLU?q7V)Di"4%%8l*KnZ'WEIqWFR"5a<51?+IbY1@`TJ`;":KCLsMLVn8YeVbekGbG[EH#l)FrpqbPVO<,/&(rP9?Ib%W)4eP_MjG4kQ[feYq]R%P!U%b:r1SV9,7K`\8c#t^VE,n5m[u0D:>AA=qBWTk([(h!!iXs'5>mj$!q%cH$OMlYtLE9GdU*MnmWk*3]\W98,7Yl]mGN=UMbZermtM,`.Jk2r]21Mk\t%hB34s+UDf]Mi'?9Gd2X^m$9Hi3Y&.gO/\E=-T8j@Ddi0V>V&A'L\qfK+C/]/PTEEV54cmB[3,.crNJ0<`\qG?[o>#*scs7DS6#m3.uq19'Xp*K3R(0":lc.>FOWGbI*4>_RQH,#\`mNo&NB.mK:_M+N5q*-V3=&+XK!'23buCeuaj7RcGT`),Xd[Di\+klp2"BL0TCBXK8KQ.OoD<"oseLf<:fWSHtrgVbUc2T7?i#DI$.Nk007S[Xo42S3`1Ncd-OZW);p;8)qUK+mq1[D[[^O>fofP_1Di$@;Xc-`N;dj6q9b2gF>'<'t5f`;,pVM*5Td_/(se0-!e*(O_LI]!8u)>M%f,CKG90Y^4#n"_Ras[Na%i<))Gk5TrfqS^5Q9\4K,?_I.?48RPek?p^U<,?b_W5.KCS@F6CiF)\/SgV.+s1&lHDmrG_(c-t-OmjQ9oB=TtHn*Y]m:f\9PCRD.otRD,t6\'H"18k_;8a*=]sRjE?cYOU7e/E;*oST3p"?'TE,%c%rBq)Kl5g>@7!DNYGtBj5.G`,(IF]*"g;7G_Q?HtT]PQRT7'1BUAFQKp[6jaqXj"k2f:a+qQuTUfB_%lZa-m(pK>&;\P\A--RU:hWWN6GZ+%3?F!@$?RCLfGPF\7=(=p3JHec1X%@K+u%=8VGmS>dT=.aiQit,dc@X125mH8WtQXc^d.Ap_!u8;?fj`kaY1kHou:hs-/h8P(e>ZiJ4pc8Xa;dZ#IS=rZH:#QR3]k04jVShH3B+PjVO,AVoJc>'%H>7]nrKu;3]NkpcA-8e%i+UM[%fRl68-%5qn!KlVLd]Qs,6l>#,&FI":MShTr%))GkiDHoI$-n6^@lgp#N0?1-^?T)`Q5Ul0GR5;@L8Y&;.(6RA=fWeqrFm1Z8KnZ!SD5%tJ6\c/*fSk?@;,pUbfAQrF*fO=Z^E@/TVpNZ3/35i'XK8Mc4_Tib)d-1_aN1#j\&?3QgsU;7q"T+)WD<[1R@=3WO3jA0g"De!MdF&@&[sRsi00`qHdWdB.I6qFpo0N5!G501H.6/[kn*CNJ.`Vd[=Pn`9o-,/EG_W%,M5pJ1^VR=0Gq-[SKe!&oME0!G,)`,=ddPecc&dZ%)e&3]e<%*K=:Z^Mn6<#4UL3^JKCErU.;di2*%O:sO[XeZ4I0(BEq/_kHaMp[7!@pFj^V0B_[l*#or;bK!C]=W(f2^u5H:(clae\acNcXr%.`iUuNgF;ENSc47=pJ"_h_bF[eUADB&X:LIQQA`LSr6P7tWB+MQ791hfqlN.'8aN_u+1VZkd:;s@'s$O8(Oq$HlO2ihZ'%!KBK:#h/Z[).SEjM*uQK$I!!;o(ujNp/$Df212I@?^tSX#K5il)9q8&q/^G:m+.N$1^(.Rccp\E2b+1*eVao]X]lEC.""eGH`84^OuN\*.I2KZ?_M2B'N:+FoMg/9iV[;4B59@HU1SifS^m3+iOi78&3Huf&RANKGKl04%/*F$mbM67Uk;,OjR8VNV%RXY53;7=ojLC\C*dl"eN]I96f,+&Bl7RTWISb_*QFXq?P)DG[@%*Da9J,UFs1^T;4R7[._6UO4\X4%Y1.kCA^h+QAFWMul,"Te[r0Ze>1(_o!]Q0G#hYhS"9&St:sS+K,kBC^P<\['VYS5<^I?Tgghd,n64k"M8([?6X]gE_*Eu-.8iRcF`JYPuiVB\Jo()7`qi7gR"q2=kQXISLEBJL8!%ffA2JgIF%gWM1mKI\OL(oF9lds1Z:'4\-C;kIc:Ra6O[sSSu(Dh;`gmOj=%NRT0<`XrZ-3Zqc:f,NID;/7$BYjMYW@(apj`lIDpOF3>OfIU!6UAP,Tg6UF+UD/I&`jr8.Y[$X+C90c94GO?I,-jU4i`3#%OBM%mWO$@Y+n$?ZQ`a&[/TXDf7n`/0.cg]o2Y@#&9QBikp2Dg1T.h3L;)s.m!"Bi3O*CT2soEU,,lW^f6_6$H7ct&Co@]`gKeZ+=-4uTFAX">kRfXKCi))E6Q*Q,e4H!dME-i!E&>NDoP/6Ti1f9=]<1,;0ri3uhh5iOJNo53?s3GrsXPFeA+X:XqL6\c0=hS":%eubDuBu4KWbB-Ai?X1-^Kq$a84F$Alp$:#O?bCWGR[T*R!LoCVXK9XhbDV46naZ.S\$qtnIX!+!%4A0Sob'&QOZU77H[.5"Uf3jOoR'XcC['Lb9[8'JM@#>d7bWji`ut^3l?:RAj'O)eAOj.Okc4$;sc"_Sa9>I=3+V*OfqB3dpksNZC3e'OY]l$Sb\YOa"-RZLqWuD8/+b6\:Elq%=jQ,C^a,d]Ff8^r&^m\iXQFXW>Vl-G&Ht@tK9bqp4`XQ1!!'mi#A7X&HAHrGFh!28@]"4?hj\2F=NF5CD96,)pdJSCBW`9,fUh\_sou;t1!s/NLoptrWT7/!J['I!S/IDKR#[PUGrr)`SQH#KDdaIU!s.7&GaX@b*UaRcF$k!G1$WscBi-^F[M_DeH]Qiu.bEq,!H%V\&mQ+3dm+=%Els[edi>)Rs;M8I_:/Ok#DKQqe0OY$8&IT'Y`[t"WW2ZaF/hTmj8O8rea2dAcPq,@b*3lr\hQUF@\[f8)KuKo`RquqY;'5E#nqr6ZaNDYg9AI_Rc_$DJ%W5,D+@XYeVDGZp^:q,-E?R(mP/2bnK8*SQ+9QY)ElaeAkjSBK+B&IT*_^9dkKK?H>8e=)eLfg,OA(_md>>8.'.Oj_ZU3iadO@-Odt\#-3dN&&HVfU4gF/tr;-HLqKP-if>WX&c?s[(;/30?,S<@m9_L'?[m[QnSQM1dFh&gprWqKl5e^NE[(s8!!@t1L6T,*+8.'.(P^9%;Fn:A*X;oT\r($2BB*"taG,Th0,"*lE\"Xg!J%!!ZtU2Mm?Q9+m+&.P)$acs6CC"&rhV.i1`70T4q5pRd(iYDg@K>i`b'06XlK*MCa(`=2gg>;>gE88ku^t@;,cAAoGh-.NI_#Q3(hnD7Io0?2'!)Q=%BIK_ESNhTfDJ:$In*eT,(hqBl77p/ZDN01BTj5pd-$gg:i2(MXcBPb=;X#6i@=FuJi510Ue^`3[Pl_R%/\MH2VJY(r\4$FK4J81`+#n3>[knQH]6CG^5>n[k]j%s`5qE_#bdMBC#eagJqXq?e!J!;2WMsUe\1si1Pu0Z`U7rj>:.34OUISn&c2rZR15)i)1Eul"(@L%m95/4G?b_V*RKeiaM_R"uaH.&_:-E7V67E:/2:F?>R(/AS#HOpu@Fr-SDU3\,[Wl\p*U<*`,S"1m.$i.PEH9Mi0qtnEA8p99q.)p=jLGqiMXG=s*p$]0c?\AS#G%IXYa8ildZA]tD"JS=K<>fs>GD.PrmDf<='J?[T]h_0,2$fu1g>qtBEU&C_A"]Qf!.)53atkeFTCfg>LuP:'/cD?'Zu.j6&ZPf)e;X]r<3nH55l^4-$,euW!or(*qn[D7jm$hEke8WcSgF*"[q[@K6p?FOh.3'8+.JN,XiTFKAI9qr\23YhbuR4Jj1V.%8r"U,(>[EB2iQplo@jM>,-?-s9mjN*J;=aHc$HhK#YV?-aC6PnHX`s,UbEA9Bse$j7&3:j;=MMd:u['ZL!T_%?mY?8&]]_tEjo]js7NXGl5G2_gQ<%\onDUl-+Y:17\bGOJ1Gq&?ZCs[`7un^WQBp.+?OmVV:.Ro@m]W:VTX_KK4n4De$FGbTl$daTO<$na8X+j,2n&T]#&_s*SIG.JXR+2WqX]j\d"J:@%L=2nkQ68,(gj&S]SW'ih!.Z,Bk&p(F[3L`>S_9TVm+=$E9j(.`%.6aW5[%?[]KVH>4$2J?1B7DW&KMld3JsFmI>V5I59NIaS=KNBeZ5pYY_\*kW:rE%ps@gOS;fBnDFf*`c^m;K^(AS_"UM:9?>t!u%Kc]W_P'>P.*&X=Di$"o.62nW4L7>C3d%HgGI`5'^&cf@IoTKKnaZ-FSih"6F$"jKpr8:49h\6lFQpZWp#grcD;)cU/-(bJBWb)Jd:h@IFh"9)6"+1F10eoZX`N[Ng(^^6W@,qB6`BEdJYrCd,6_b#kMbA3&e]dsHt`%miPL;&$Q!P]LgKJM"ot2;+X)DW6pH.u(q2=VTM.A>^sLGiF0W9d\]Sq<^9%\:34bkPCAIMN:XO(u@]q((-(R2G[U6duC5_ZRne/:[!!)N0eZ2b#a0e*a4O)!iTegIi]6<::AlVj]^juTQjiAVe(L!3MR57>X&)um>b'oIQ>$?76aq_L^/1iFWXW7BA6:5HPk0KZ\>F47r?TO>.r(Z7=?[bj(7n2tC042H;`dJgjI(6i%>gpR9S2ir!s"mI0(Q-in$efGD]YH\Za7!u:uK?Q)eEk0',)$LN#4k4-9HD;i#KjXp$1(lAa8?e:&rX._Sa8?a*;uZ4Dnk"iT9/iB.X^am`qr9X"<]![K'aKR$=-AK?h+>gBl#mgo$HhO6d7p[\X!dni:X/`1oCn)_?Npoq1!!!X?n`%OKOhQ#+>26]6L1+#HJoThjYq.@L,@eWG%1G\Iikr@SUo1+h2NA9NEreNj.5*?P4?DHdlAAdaDe*Hl14'RcO,o@UEaiNgJ,T%Ak&P4eW[0ukUebrK0P1,lB4p7j"onYLUo("eNq_c$B\_$\+?)6g?G1Z"SHs;nq4sg^.9!+B/Hde:_?A8d-=sj']d_\@3F^dl!!(rLTV*FuGXms4\Xsij.4Jue]!Y_bJ*PN4L-gn?3Prda.+l4[[qN1512(5hffhI3r=8o#(Wp8kaQ4"6M[r:.>\W5*k/hk/`OX"j=!rtS7[Vabg*qe+8f!ojBK]0/).bCh/UFTd7b*&eL*5s[eG<`@ud)`EY\Q/m02'*&#ujQG]Ur:.hgJY/O*Na!E+.P!%&)#Q*u`mC!4S=Ig>K,A:mp+IX8A,lQ,hVR*OZJ7huIY/!!!91jjC`,/R-A/!r:cj"#^@U_19/0]5r$;"t\VE]mfq6`5G&`0o*Q!o&@ZK)jIH-#=\\Y[u$!"+qOVAj2XeKit?p<7uss\p1U$k=2Me+#<=jXKThT5g#86]PT\kZ)Gs+>&ed&g))<*CirXbVoA[^so%=!@pYTuV;@aD^`meX3AC-UGF6?4t_Q=1G!5Z3ek72e4UU_[g?*p7r5"fB,'bs/?_Xls:[;ln=>eG;Yj9C_JPT/JfD;0eL(B=GEE:`3dZ3:LA$cB*)Q?267Z*EID>IL>$s,iG+Tr"Z[j0R&qPJuYe17k)/>*^j^i^@g>n=g?l!9rP+k!lcZEH-!.F\u(D?I%!!)]9NU5>SLjb@lc\K5:/Hfi-(1+[,ff?>@\toYf@&'^:q<4%D/mM0f]qqn(tacneO('jfAoZk09CMgY6LB!bJ5Y.DHZ&!.]:7PK?:R)G)i_hX]dO=k`R(A&])(qpqlR[Ib8G^A-[q>YUnT++O3.bEa`f.=lMfGO3s:^(^VK+:J,Fr!7J=;lA5L$GP7HhZrBkq^=RR5+qUCM8R!$G!^Xg(ZkKUC!h.!C./=8%9QpA4T-X"`@T[W6MJ?i;3-4M@\TaEH,63"YILfp)EGni/XN=rr2oN'Jb.8GX@l:)]SCF&-)\J&Jc-OYQg:<9p4W>\ql.JND+c,B$Ho2I>ZTVS=Kg(X&lLEh&%+tN`Ap[/N;dSEt(g530>kV!!()uf[s;X6'sTLSi$2FE]Ef%Df(["g<,KL0'e=6]U*_-26rTT4Y[KoErdp;a!sdh'#*'B6(Fs9p9f_8mZ*^n!9-aK;EhoA$TP)TBWb,\q\okMO;=jMK>CN+E#B7-Q7oV9sE"65NH%aYgabaB(!!((MA6#L%SZ6EB,TG#Q-RYffT0@k=$@7d6ghji\Vb`p7X2$_1Lm=5?\NsQ8HH!'e!!)(N9hc(#J>aBAh7Imk(.CqtCOceZ2^Ca2Z,^YG"$%K[q9@7ZF-XMQ3[+J[GR[+A:/2dL6QoQ+"QG_#_"h-:1'e3@lQi5Q(#'U4a1-:2':;TV*F/2:_cuOoM/M,/Q4hY$Ieb!gB7Khn=A\\jgXYE=o#O!!(*'daD$'@q2@S\8^C.DFI6`Q^:Y=*E()PkKakh:rYM.5dF6;$(.*IW628K]/JULAQZpQX=VnO:JOZf=0EZNo`kmB+CZVs!0A]h2E"1>EV]0:giCp6il-fd557Af?dPoZ2s&?f!Wq$SE9,*&jS8=E_oKfQ+FDY=D&3:_7t\?ta5PqHJphTo9pLN\WgPG)D07RQ#.[(/-^=Tc+=)dA'2h2)T.?YfNO@!!"-!o()@#pu)I3)3MlSeWQ(.p,T7&I!h/C6tVbHY7uBWeQ6G0O0PQmMMmD)G3qnf3cjFWe]W.)hQ?Y+Rl>7\SiiFOZ=oAPX&8ota;rfF.P`unjfj?ukAio36HVF-bQJ%Oi2S#Qm-O(>X]eSZI/NcEo!5;tY7ggq@))d)3i`0!!!%Ng[r:/)Qk]07\@&OB/JBP1jTHVgI&QrLEgIai!,p`,)1,hrW2M*KKuu&.QS)RlW+seZ:R>eB0E;(uaP41B5Pa@R"8N(_WiE'C6j=n-h07bUr^?!$254g6VW$Lm\>mZPH2mmBMT[h>T'>@uKr[ZC!9bmY,pdWpbX!#a_nuSc(:L/9;h^a:nm^[(1pXKgm+Sj?jP@RrH$Kc6/nA"JR@0J6SZVUdLFPB0mY(@m!!!;Ffs><#A2R;n['XAJR=tK1QS2]XDf5q=C=Geb@ocEfZVqq;?sr9LW>b/1*]@h:I!iR4q>gTCF$`5]%K:QqPE`&FW*hNTWkk?m.:kLqHhM:79Qb_cLgaN/bOI;HY^!i@#pS<'h%-e!!$D=hnFN_G+NY93=;pTE)nU.p#/$5qU[D/J?G\ULa!!$K5Ni()@[k.JE#TVjo@4XBDls$\.m:)<\lIn`J(84rP@?!'k`6$k++8E1f\/<23,)dF$@s/GAAZWu6eSM2C1lX>[.b\Phbe"onYM&]2H']6E_HW?E9:@YCU;8ki%11nQj=e##i]"VqmjCK_W`BR^-t!!#7h?k\EZba2[c=]AA=iHE8%*RjXegUD+!.rE+S"WYJP!kPcTXUY=2TF:Pipi*I0A&aJdG1>s)Rl;=)8%0*;$Obuk)NR",oLQUV#64ac0cVD*euD`nc-;7&m0X4/\_67TIee]'5U.KuD?]S:bC'No!!'TcVE8^7gpj'&f%+j$`c3farVH13Q^3u)a/q1Iq>'3G[+TV4l2ZbpAUbGOJiibN'8B7ao):!!!#["f4B[rV,4Fc#m>l<2@3mp@\))'W];U0-*/<4aCj#!!!#`6YQu#oCMdkbM'@>[5ZLoDsO/gO4M$II^sh"0#(*c!!"-QaN=F+5D]:/j\*<]1uZF-q!mD?.[`dZ?G+?t!s/H&8MbJ+:JoI+`.!'&F':2Xj^%^K=WA6$Pj!!;$:KD'g+8=0Gs#=MBu_'9C0/j,ZE*29t(8hE2S!00OXR84lM6YpBDN!$k*==rP6R"U52%3s!5(Ynl@%[1$,0$?Za1=^11t64.rV\7ku&[B_(WEDm>?dY,'Xd^3)W[R4ZkikZ+l\#1E8W.**lKA;o@59!<<,X"nI&4(J@b3=t5V.*^+hV;IOs#]KgZQLo*n9IeMH-P^d.Up>*?)UC0hh5-=d)!<<,XSVW(-RkhN/7^OO4-@\.b-\XnBFRsE=ihgkU3%e3-r=coUnje`UIM4h&/H%Ym@sgb!"^2^N<]t8XL)90V5;ti@9=GH^ANKZqDBoqf\"iD>A>`=nGN*'AV1[5([p(cMf?MXSNF6-XoJG%@Sp!"0lc2@L&'H4E?hqZrqPLa8qYg3It-##1AlTKDqD-4O/7[8C&pb%Pa%E&3d$=-6)RJKWiE(DGch#H!+LNGr8P\R'h0`:4IebFldi25[$dnmWN)<@\ogY2""ed47rm&,e#faSl)mTQ:?L`5!WW4VMh?Wa11GumL)`DAg=tAGmGX[er^jUN-722I)_GoMn)!Hlj$WV85p.9mJ>\//!!%P#=0GrO9V+@Lm58P%SDi]e!WW4.""cllJq>iX4u'$=n2%S!!!#[b3,CH:,%Wk_#pa14b!q&>LL[U>dU_LaR;f;?!!&\%\``^Cu2g-bXVa8!$DXTR1if5CrnBa:.\$nA]+$>]6ODW!9bO.aDuHIB"0fW1_c9&`s'BG$ig8-pkRp#R$3A**`NiBp?gTj+!)5M"q;Kha2a,3'EA+5j@aN61:!;Tj(W+;`dG%a=V9mH.Okc2#S?BHZY%H3/hRp;nGrUiF9#i-J,8CWKaB&\5Tt+7gc6q"@nc*T$`P"qQ/]mKKKfHpe&!75H8h;+2R4`]V>g+1:chAHS-%+N_BVl-FCDd?LK8^7jC-.f;*'=(mE!!)YFkic[^RV5k->[:W[1ULI$p.\Jng8PXKJ_/q(G9[H$O[aIXZ*K'cr!3H_2!2,B@77FJdfZ7)DXq(sNrUeQ7\X@lb(O!*7?G1Z).o90A9q)n;)_5e.!rr>b34ZT1CgL*jh\r1+^.+aWNYa?Tbg4TOX!%KD!;%(':JYSlChmfZp^(,hq"srL*^*\*o=eh]Rafhd8f;;RKTrQD]=)G&VVHQSZ*CR?ZZB_jVXSF,!!!#s+'D`Lbb=(op$5-D@2dDaDr/,eA]b^HXSr(moBA#F.4?c"IJ``?]=[ss]mCPH=>5!hi30lkWaWf"FmIUqd\KHi%NU#ni[(nCQ1_d)FJ3NT)!69N]'E~>endstream endobj -31 0 obj +35 0 obj << /BitsPerComponent 8 /ColorSpace /DeviceGray /Decode [ 0 1 ] /Filter [ /ASCII85Decode /FlateDecode ] /Height 523 /Length 102 /Subtype /Image /Type /XObject /Width 535 @@ -247,11 +283,11 @@ endobj stream Gb"0;0`_7S!5bE.WFlYNTE"rlzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz%La%hpV[~>endstream endobj -32 0 obj +36 0 obj << -/Contents 94 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 80 0 R /Resources << +/Contents 106 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 89 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] /XObject << -/FormXob.d3ecd28ca03f587d6940049748681018 3 0 R /FormXob.fc331aff86ff817ecac4c4ce4b2ecd3a 30 0 R +/FormXob.d3ecd28ca03f587d6940049748681018 3 0 R /FormXob.fc331aff86ff817ecac4c4ce4b2ecd3a 34 0 R >> >> /Rotate 0 /Trans << @@ -259,9 +295,9 @@ endobj /Type /Page >> endobj -33 0 obj +37 0 obj << -/Contents 95 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 80 0 R /Resources << +/Contents 107 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 89 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << @@ -269,254 +305,279 @@ endobj /Type /Page >> endobj -34 0 obj -<< -/Outlines 36 0 R /PageLabels 96 0 R /PageMode /UseNone /Pages 80 0 R /Type /Catalog ->> -endobj -35 0 obj -<< -/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 -36 0 obj -<< -/Count 52 /First 37 0 R /Last 37 0 R /Type /Outlines ->> -endobj -37 0 obj -<< -/Count 42 /Dest [ 10 0 R /XYZ 57.02362 525.9477 0 ] /First 38 0 R /Last 79 0 R /Parent 36 0 R /Title (Feedback Is All You Need) ->> -endobj 38 0 obj << -/Dest [ 10 0 R /XYZ 57.02362 370.4013 0 ] /Next 39 0 R /Parent 37 0 R /Title (Abstract) +/Outlines 40 0 R /PageLabels 108 0 R /PageMode /UseNone /Pages 89 0 R /Type /Catalog >> endobj 39 0 obj << -/Dest [ 11 0 R /XYZ 57.02362 765.0236 0 ] /Next 40 0 R /Parent 37 0 R /Prev 38 0 R /Title (1. The Problem: Interpreters That Cannot Feed Back) +/Author () /CreationDate (D:20260416181050-04'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260416181050-04'00') /Producer (ReportLab PDF Library - \(opensource\)) + /Subject (\(unspecified\)) /Title () /Trapped /False >> endobj 40 0 obj << -/Count 2 /Dest [ 11 0 R /XYZ 57.02362 557.8236 0 ] /First 41 0 R /Last 42 0 R /Next 43 0 R /Parent 37 0 R - /Prev 39 0 R /Title (2. Architecture: One File, Two Evaluators) +/Count 57 /First 41 0 R /Last 41 0 R /Type /Outlines >> endobj 41 0 obj << -/Dest [ 11 0 R /XYZ 57.02362 372.6236 0 ] /Next 42 0 R /Parent 40 0 R /Title (2.1 Type System) +/Count 47 /Dest [ 10 0 R /XYZ 57.02362 525.9477 0 ] /First 42 0 R /Last 88 0 R /Parent 40 0 R /Title (Feedback Is All You Need) >> endobj 42 0 obj << -/Dest [ 11 0 R /XYZ 57.02362 136.6236 0 ] /Parent 40 0 R /Prev 41 0 R /Title (2.2 The Bytecode) +/Dest [ 10 0 R /XYZ 57.02362 370.4013 0 ] /Next 43 0 R /Parent 41 0 R /Title (Abstract) >> endobj 43 0 obj << -/Dest [ 12 0 R /XYZ 57.02362 411.0236 0 ] /Next 44 0 R /Parent 37 0 R /Prev 40 0 R /Title (3. The Explicit Frame Stack) +/Dest [ 11 0 R /XYZ 57.02362 573.0236 0 ] /Next 44 0 R /Parent 41 0 R /Prev 42 0 R /Title (1. The Problem: Interpreters That Cannot Feed Back) >> endobj 44 0 obj << -/Count 2 /Dest [ 13 0 R /XYZ 57.02362 711.0236 0 ] /First 45 0 R /Last 46 0 R /Next 47 0 R /Parent 37 0 R - /Prev 43 0 R /Title (4. Continuations: Feedback as a Data Structure) +/Count 2 /Dest [ 11 0 R /XYZ 57.02362 365.8236 0 ] /First 45 0 R /Last 46 0 R /Next 47 0 R /Parent 41 0 R + /Prev 43 0 R /Title (2. Architecture: One File, Two Evaluators) >> endobj 45 0 obj << -/Dest [ 13 0 R /XYZ 57.02362 303.4236 0 ] /Next 46 0 R /Parent 44 0 R /Title (4.1 Generators from Continuations) +/Dest [ 11 0 R /XYZ 57.02362 180.6236 0 ] /Next 46 0 R /Parent 44 0 R /Title (2.1 Type System) >> endobj 46 0 obj << -/Dest [ 15 0 R /XYZ 57.02362 727.0236 0 ] /Parent 44 0 R /Prev 45 0 R /Title (4.2 Why "Feedback Is All You Need") +/Dest [ 12 0 R /XYZ 57.02362 637.0236 0 ] /Parent 44 0 R /Prev 45 0 R /Title (2.2 The Bytecode) >> endobj 47 0 obj << -/Count 3 /Dest [ 15 0 R /XYZ 57.02362 553.0236 0 ] /First 48 0 R /Last 50 0 R /Next 51 0 R /Parent 37 0 R - /Prev 44 0 R /Title (5. Optimizations) +/Dest [ 12 0 R /XYZ 57.02362 227.0236 0 ] /Next 48 0 R /Parent 41 0 R /Prev 44 0 R /Title (3. The Explicit Frame Stack) >> endobj 48 0 obj << -/Dest [ 15 0 R /XYZ 57.02362 525.8236 0 ] /Next 49 0 R /Parent 47 0 R /Title (5.1 Peephole Optimizer) +/Count 3 /Dest [ 13 0 R /XYZ 57.02362 548.6236 0 ] /First 49 0 R /Last 51 0 R /Next 52 0 R /Parent 41 0 R + /Prev 47 0 R /Title (4. Continuations: Feedback as a Data Structure) >> endobj 49 0 obj << -/Dest [ 15 0 R /XYZ 57.02362 379.8236 0 ] /Next 50 0 R /Parent 47 0 R /Prev 48 0 R /Title (5.2 Inline Cache) +/Dest [ 13 0 R /XYZ 57.02362 141.0236 0 ] /Next 50 0 R /Parent 48 0 R /Title (4.1 Generators from Continuations) >> endobj 50 0 obj << -/Dest [ 15 0 R /XYZ 57.02362 179.8236 0 ] /Parent 47 0 R /Prev 49 0 R /Title (5.3 Constant Folding) +/Dest [ 15 0 R /XYZ 57.02362 561.8236 0 ] /Next 51 0 R /Parent 48 0 R /Prev 49 0 R /Title (4.2 Why "Feedback Is All You Need") >> endobj 51 0 obj << -/Count 3 /Dest [ 16 0 R /XYZ 57.02362 723.0236 0 ] /First 52 0 R /Last 54 0 R /Next 55 0 R /Parent 37 0 R - /Prev 47 0 R /Title (6. Benchmarks: Three Evaluators vs CPython) +/Dest [ 15 0 R /XYZ 57.02362 361.8236 0 ] /Parent 48 0 R /Prev 50 0 R /Title (4.3 Three Scopes of Feedback) >> endobj 52 0 obj << -/Dest [ 16 0 R /XYZ 57.02362 663.8236 0 ] /Next 53 0 R /Parent 51 0 R /Title (6.1 Raw Results) +/Count 3 /Dest [ 15 0 R /XYZ 57.02362 151.8236 0 ] /First 53 0 R /Last 55 0 R /Next 56 0 R /Parent 41 0 R + /Prev 48 0 R /Title (5. Optimizations) >> endobj 53 0 obj << -/Dest [ 16 0 R /XYZ 57.02362 397.8236 0 ] /Next 54 0 R /Parent 51 0 R /Prev 52 0 R /Title (6.2 Analysis) +/Dest [ 15 0 R /XYZ 57.02362 124.6236 0 ] /Next 54 0 R /Parent 52 0 R /Title (5.1 Peephole Optimizer) >> endobj 54 0 obj << -/Dest [ 16 0 R /XYZ 57.02362 191.8236 0 ] /Parent 51 0 R /Prev 53 0 R /Title (6.3 What the Benchmarks Test) +/Dest [ 16 0 R /XYZ 57.02362 673.0236 0 ] /Next 55 0 R /Parent 52 0 R /Prev 53 0 R /Title (5.2 Inline Cache) >> endobj 55 0 obj << -/Count 4 /Dest [ 17 0 R /XYZ 57.02362 699.0236 0 ] /First 56 0 R /Last 59 0 R /Next 60 0 R /Parent 37 0 R - /Prev 51 0 R /Title (7. Portal: Machine State Serialization) +/Dest [ 16 0 R /XYZ 57.02362 473.0236 0 ] /Parent 52 0 R /Prev 54 0 R /Title (5.3 Constant Folding) >> endobj 56 0 obj << -/Dest [ 17 0 R /XYZ 57.02362 639.8236 0 ] /Next 57 0 R /Parent 55 0 R /Title (7.1 Serialization) +/Count 3 /Dest [ 16 0 R /XYZ 57.02362 313.0236 0 ] /First 57 0 R /Last 59 0 R /Next 60 0 R /Parent 41 0 R + /Prev 52 0 R /Title (6. Benchmarks: Three Evaluators vs CPython) >> endobj 57 0 obj << -/Dest [ 17 0 R /XYZ 57.02362 487.8236 0 ] /Next 58 0 R /Parent 55 0 R /Prev 56 0 R /Title (7.2 Deserialization) +/Dest [ 16 0 R /XYZ 57.02362 253.8236 0 ] /Next 58 0 R /Parent 56 0 R /Title (6.1 Raw Results) >> endobj 58 0 obj << -/Dest [ 17 0 R /XYZ 57.02362 377.8236 0 ] /Next 59 0 R /Parent 55 0 R /Prev 57 0 R /Title (7.3 Checkpoint & Resume) +/Dest [ 17 0 R /XYZ 57.02362 685.0236 0 ] /Next 59 0 R /Parent 56 0 R /Prev 57 0 R /Title (6.2 Analysis) >> endobj 59 0 obj << -/Dest [ 18 0 R /XYZ 57.02362 765.0236 0 ] /Parent 55 0 R /Prev 58 0 R /Title (7.4 Use Case: Distributed Primality Testing) +/Dest [ 17 0 R /XYZ 57.02362 479.0236 0 ] /Parent 56 0 R /Prev 58 0 R /Title (6.3 What the Benchmarks Test) >> endobj 60 0 obj << -/Count 6 /Dest [ 18 0 R /XYZ 57.02362 564.2236 0 ] /First 61 0 R /Last 66 0 R /Next 67 0 R /Parent 37 0 R - /Prev 55 0 R /Title (8. The EML Universality Proof) +/Count 7 /Dest [ 17 0 R /XYZ 57.02362 281.0236 0 ] /First 61 0 R /Last 67 0 R /Next 68 0 R /Parent 41 0 R + /Prev 56 0 R /Title (7. Portal: Feedback Across Time) >> endobj 61 0 obj << -/Dest [ 18 0 R /XYZ 57.02362 487.0236 0 ] /Next 62 0 R /Parent 60 0 R /Title (8.1 The Operator) +/Dest [ 19 0 R /XYZ 57.02362 765.0236 0 ] /Next 62 0 R /Parent 60 0 R /Title (7.1 S-Expression Portal \204 the Portable One) >> endobj 62 0 obj << -/Dest [ 18 0 R /XYZ 57.02362 410.2236 0 ] /Next 63 0 R /Parent 60 0 R /Prev 61 0 R /Title (8.2 Stage 1: Core Functions \(Depth 1--3\)) +/Dest [ 19 0 R /XYZ 57.02362 523.8236 0 ] /Next 63 0 R /Parent 60 0 R /Prev 61 0 R /Title (7.2 Cross-Implementation Exchange Matrix) >> endobj 63 0 obj << -/Dest [ 18 0 R /XYZ 57.02362 290.2236 0 ] /Next 64 0 R /Parent 60 0 R /Prev 62 0 R /Title (8.3 Stage 2: Arithmetic) +/Dest [ 19 0 R /XYZ 57.02362 323.8236 0 ] /Next 64 0 R /Parent 60 0 R /Prev 62 0 R /Title (7.3 JSON Portal \204 Graph-Aware, Continuation-Preserving) >> endobj 64 0 obj << -/Dest [ 18 0 R /XYZ 57.02362 175.8236 0 ] /Next 65 0 R /Parent 60 0 R /Prev 63 0 R /Title (8.4 Stage 3: Complex Plane Access) +/Dest [ 20 0 R /XYZ 57.02362 739.0236 0 ] /Next 65 0 R /Parent 60 0 R /Prev 63 0 R /Title (7.4 Binary Heap Dump \204 the Fast One) >> endobj 65 0 obj << -/Dest [ 19 0 R /XYZ 57.02362 765.0236 0 ] /Next 66 0 R /Parent 60 0 R /Prev 64 0 R /Title (8.5 Stage 4: Trigonometry via Euler) +/Dest [ 20 0 R /XYZ 57.02362 487.0236 0 ] /Next 66 0 R /Parent 60 0 R /Prev 64 0 R /Title (7.5 Cross-Process Benchmarks) >> endobj 66 0 obj << -/Dest [ 19 0 R /XYZ 57.02362 669.0236 0 ] /Parent 60 0 R /Prev 65 0 R /Title (8.6 Verification & Friction Analysis) +/Dest [ 20 0 R /XYZ 57.02362 185.0236 0 ] /Next 67 0 R /Parent 60 0 R /Prev 65 0 R /Title (7.6 Mismatch Cases: Graceful Degradation) >> endobj 67 0 obj << -/Dest [ 19 0 R /XYZ 57.02362 165.8236 0 ] /Next 68 0 R /Parent 37 0 R /Prev 60 0 R /Title (9. Language Coverage) +/Dest [ 21 0 R /XYZ 57.02362 601.0236 0 ] /Parent 60 0 R /Prev 66 0 R /Title (7.7 Use Case: Distributed Primality Testing) >> endobj 68 0 obj << -/Dest [ 21 0 R /XYZ 57.02362 621.0236 0 ] /Next 69 0 R /Parent 37 0 R /Prev 67 0 R /Title (10. Relationship to Companion Papers) +/Count 6 /Dest [ 21 0 R /XYZ 57.02362 400.2236 0 ] /First 69 0 R /Last 74 0 R /Next 75 0 R /Parent 41 0 R + /Prev 60 0 R /Title (8. The EML Universality Proof) >> endobj 69 0 obj << -/Count 1 /Dest [ 21 0 R /XYZ 57.02362 371.8236 0 ] /First 70 0 R /Last 70 0 R /Next 71 0 R /Parent 37 0 R - /Prev 68 0 R /Title (11. Four Implementations, One Language) +/Dest [ 21 0 R /XYZ 57.02362 323.0236 0 ] /Next 70 0 R /Parent 68 0 R /Title (8.1 The Operator) >> endobj 70 0 obj << -/Dest [ 22 0 R /XYZ 57.02362 607.0236 0 ] /Parent 69 0 R /Title (11.1 Test Coverage) +/Dest [ 21 0 R /XYZ 57.02362 246.2236 0 ] /Next 71 0 R /Parent 68 0 R /Prev 69 0 R /Title (8.2 Stage 1: Core Functions \(Depth 1--3\)) >> endobj 71 0 obj << -/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) +/Dest [ 22 0 R /XYZ 57.02362 765.0236 0 ] /Next 72 0 R /Parent 68 0 R /Prev 70 0 R /Title (8.3 Stage 2: Arithmetic) >> endobj 72 0 obj << -/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) +/Dest [ 22 0 R /XYZ 57.02362 650.6236 0 ] /Next 73 0 R /Parent 68 0 R /Prev 71 0 R /Title (8.4 Stage 3: Complex Plane Access) >> endobj 73 0 obj << -/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) +/Dest [ 22 0 R /XYZ 57.02362 542.6236 0 ] /Next 74 0 R /Parent 68 0 R /Prev 72 0 R /Title (8.5 Stage 4: Trigonometry via Euler) >> endobj 74 0 obj << -/Dest [ 24 0 R /XYZ 57.02362 485.0236 0 ] /Parent 71 0 R /Prev 73 0 R /Title (12.3 Our Shared Infrastructure) +/Dest [ 22 0 R /XYZ 57.02362 446.6236 0 ] /Parent 68 0 R /Prev 73 0 R /Title (8.6 Verification & Friction Analysis) >> endobj 75 0 obj << -/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) +/Dest [ 24 0 R /XYZ 57.02362 641.8236 0 ] /Next 76 0 R /Parent 41 0 R /Prev 68 0 R /Title (9. Language Coverage) >> endobj 76 0 obj << -/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) +/Dest [ 24 0 R /XYZ 57.02362 392.6236 0 ] /Next 77 0 R /Parent 41 0 R /Prev 75 0 R /Title (10. Relationship to Companion Papers) >> endobj 77 0 obj << -/Dest [ 29 0 R /XYZ 57.02362 135.0236 0 ] /Next 78 0 R /Parent 37 0 R /Prev 76 0 R /Title (Citation) +/Count 2 /Dest [ 24 0 R /XYZ 57.02362 143.4236 0 ] /First 78 0 R /Last 79 0 R /Next 80 0 R /Parent 41 0 R + /Prev 76 0 R /Title (11. Three Implementations, One Language) >> endobj 78 0 obj << -/Dest [ 32 0 R /XYZ 57.02362 765.0236 0 ] /Next 79 0 R /Parent 37 0 R /Prev 77 0 R /Title (References) +/Dest [ 25 0 R /XYZ 57.02362 337.0236 0 ] /Next 79 0 R /Parent 77 0 R /Title (11.1 Test Coverage) >> endobj 79 0 obj << -/Dest [ 32 0 R /XYZ 57.02362 683.8236 0 ] /Parent 37 0 R /Prev 78 0 R /Title (License) +/Dest [ 25 0 R /XYZ 57.02362 131.0236 0 ] /Parent 77 0 R /Prev 78 0 R /Title (11.2 File I/O Parity) >> 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 24 0 R 29 0 R 32 0 R 33 0 R ] /Type /Pages +/Count 3 /Dest [ 26 0 R /XYZ 57.02362 519.0236 0 ] /First 81 0 R /Last 83 0 R /Next 84 0 R /Parent 41 0 R + /Prev 77 0 R /Title (12. MOAD Audit: Fixing What We Built) >> endobj 81 0 obj << -/Length 4413 +/Dest [ 26 0 R /XYZ 57.02362 471.8236 0 ] /Next 82 0 R /Parent 80 0 R /Title (12.1 MOAD-0001: The Sedimentary Defect in Our Own Code) +>> +endobj +82 0 obj +<< +/Dest [ 26 0 R /XYZ 57.02362 103.0236 0 ] /Next 83 0 R /Parent 80 0 R /Prev 81 0 R /Title (12.2 MOAD-0002: The Intertangle in Our Own Design) +>> +endobj +83 0 obj +<< +/Dest [ 30 0 R /XYZ 57.02362 559.0236 0 ] /Parent 80 0 R /Prev 82 0 R /Title (12.3 Our Shared Infrastructure) +>> +endobj +84 0 obj +<< +/Dest [ 30 0 R /XYZ 57.02362 343.0236 0 ] /Next 85 0 R /Parent 41 0 R /Prev 80 0 R /Title (13. Future Work) +>> +endobj +85 0 obj +<< +/Dest [ 30 0 R /XYZ 57.02362 189.8236 0 ] /Next 86 0 R /Parent 41 0 R /Prev 84 0 R /Title (14. The Defect in the Model) +>> +endobj +86 0 obj +<< +/Dest [ 33 0 R /XYZ 57.02362 201.0236 0 ] /Next 87 0 R /Parent 41 0 R /Prev 85 0 R /Title (Citation) +>> +endobj +87 0 obj +<< +/Dest [ 36 0 R /XYZ 57.02362 765.0236 0 ] /Next 88 0 R /Parent 41 0 R /Prev 86 0 R /Title (References) +>> +endobj +88 0 obj +<< +/Dest [ 36 0 R /XYZ 57.02362 683.8236 0 ] /Parent 41 0 R /Prev 87 0 R /Title (License) +>> +endobj +89 0 obj +<< +/Count 18 /Kids [ 10 0 R 11 0 R 12 0 R 13 0 R 15 0 R 16 0 R 17 0 R 19 0 R 20 0 R 21 0 R + 22 0 R 24 0 R 25 0 R 26 0 R 30 0 R 33 0 R 36 0 R 37 0 R ] /Type /Pages +>> +endobj +90 0 obj +<< +/Length 4748 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET @@ -599,115 +660,214 @@ 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 Q Q q -1 0 0 1 57.02362 271.2013 cm +1 0 0 1 57.02362 259.2013 cm q -BT 1 0 0 1 0 26 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 (to a continuation captured & invoked.) Tj T* ET +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 Q Q q -1 0 0 1 57.02362 157.2013 cm +1 0 0 1 57.02362 241.2013 cm q -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 +BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (uncommonlisp) Tj /F1 10 Tf ( proves this by implementing R7RS Scheme three ways:) Tj T* ET Q Q q -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 +1 0 0 1 57.02362 235.2013 cm Q q -1 0 0 1 57.02362 85.20126 cm +1 0 0 1 57.02362 235.2013 cm +Q +q +1 0 0 1 57.02362 211.2013 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 +BT /F1 10 Tf 12 TL ET +q +1 0 0 1 6 9 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 5.736213 Tw 12 TL /F3 10 Tf 0 0 0 rg (Python bytecode VM) Tj /F1 10 Tf ( \227 3,678 lines, full first-class continuations, JSON portal, reference) Tj T* 0 Tw (implementation) Tj T* ET +Q +Q +q +Q +Q +Q +q +1 0 0 1 57.02362 205.2013 cm +Q +q +1 0 0 1 57.02362 181.2013 cm +q +0 0 0 rg +BT /F1 10 Tf 12 TL ET +q +1 0 0 1 6 9 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 .220556 Tw 12 TL /F3 10 Tf 0 0 0 rg (C interpreter + x86_64 JIT) Tj /F1 10 Tf ( \227 ~9,000 lines, 7--10\327 faster than CPython on recursive workloads, JSON) Tj T* 0 Tw (portal) Tj T* ET +Q +Q +q +Q +Q +Q +q +1 0 0 1 57.02362 175.2013 cm +Q +q +1 0 0 1 57.02362 151.2013 cm +q +0 0 0 rg +BT /F1 10 Tf 12 TL ET +q +1 0 0 1 6 9 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 .332739 Tw 12 TL /F3 10 Tf 0 0 0 rg (Pure x86_64 assembly) Tj /F1 10 Tf ( \227 4,455 lines, 22 KB stripped binary, zero external dependencies, 79 builtins,) Tj T* 0 Tw (binary heap-dump portal) Tj T* ET +Q +Q +q +Q +Q +Q +q +1 0 0 1 57.02362 133.2013 cm +Q +q +1 0 0 1 57.02362 79.20126 cm +q +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 endstream endobj -82 0 obj +91 0 obj << -/Length 8838 +/Length 8385 >> 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 729.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 675.0236 cm +q +BT 1 0 0 1 0 38 Tm .925596 Tw 12 TL /F1 10 Tf 0 0 0 rg (974+ verified assertions pass identically across the three implementations \(571 Python unit, 131 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 621.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 .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 591.0236 cm +q +0 0 0 rg +BT 1 0 0 1 0 14 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 (S-expressions are its mechanism across implementations. One file is the proof \227 by three translations.) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 559.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 683.8236 cm +1 0 0 1 57.02362 491.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 629.8236 cm +1 0 0 1 57.02362 437.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 575.8236 cm +1 0 0 1 57.02362 383.8236 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 1.513223 Tw (on the C stack, or require CPS transformation that obscures the source. uncommonlisp takes a different) Tj T* 0 Tw (path: an 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 544.6236 cm +1 0 0 1 57.02362 352.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 524.6236 cm +1 0 0 1 57.02362 332.6236 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (uncommonlisp implements two evaluation strategies in a single 3,261-line Python file:) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (uncommonlisp implements two evaluation strategies in a single 3,678-line Python file:) Tj T* ET Q Q q -1 0 0 1 57.02362 482.6236 cm +1 0 0 1 57.02362 290.6236 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 440.6236 cm +1 0 0 1 57.02362 248.6236 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 386.6236 cm +1 0 0 1 57.02362 194.6236 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 360.6236 cm +1 0 0 1 57.02362 168.6236 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 342.6236 cm +1 0 0 1 57.02362 150.6236 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 336.6236 cm +1 0 0 1 57.02362 144.6236 cm Q q -1 0 0 1 57.02362 336.6236 cm +1 0 0 1 57.02362 144.6236 cm Q q -1 0 0 1 57.02362 324.6236 cm +1 0 0 1 57.02362 132.6236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -729,10 +889,10 @@ Q Q Q q -1 0 0 1 57.02362 318.6236 cm +1 0 0 1 57.02362 126.6236 cm Q q -1 0 0 1 57.02362 306.6236 cm +1 0 0 1 57.02362 114.6236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -754,10 +914,10 @@ Q Q Q q -1 0 0 1 57.02362 300.6236 cm +1 0 0 1 57.02362 108.6236 cm Q q -1 0 0 1 57.02362 288.6236 cm +1 0 0 1 57.02362 96.62362 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -779,10 +939,10 @@ Q Q Q q -1 0 0 1 57.02362 282.6236 cm +1 0 0 1 57.02362 90.62362 cm Q q -1 0 0 1 57.02362 270.6236 cm +1 0 0 1 57.02362 78.62362 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -804,10 +964,19 @@ Q Q Q q -1 0 0 1 57.02362 264.6236 cm +1 0 0 1 57.02362 72.62362 cm Q + +endstream +endobj +92 0 obj +<< +/Length 6935 +>> +stream +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 57.02362 252.6236 cm +1 0 0 1 57.02362 753.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -829,10 +998,10 @@ Q Q Q q -1 0 0 1 57.02362 246.6236 cm +1 0 0 1 57.02362 747.0236 cm Q q -1 0 0 1 57.02362 234.6236 cm +1 0 0 1 57.02362 735.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -854,10 +1023,10 @@ Q Q Q q -1 0 0 1 57.02362 228.6236 cm +1 0 0 1 57.02362 729.0236 cm Q q -1 0 0 1 57.02362 216.6236 cm +1 0 0 1 57.02362 717.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -879,10 +1048,10 @@ Q Q Q q -1 0 0 1 57.02362 210.6236 cm +1 0 0 1 57.02362 711.0236 cm Q q -1 0 0 1 57.02362 198.6236 cm +1 0 0 1 57.02362 699.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -904,43 +1073,34 @@ Q Q Q q -1 0 0 1 57.02362 180.6236 cm +1 0 0 1 57.02362 681.0236 cm Q q -1 0 0 1 57.02362 150.6236 cm +1 0 0 1 57.02362 651.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 124.6236 cm +1 0 0 1 57.02362 625.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 106.6236 cm +1 0 0 1 57.02362 607.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 88.62362 cm +1 0 0 1 57.02362 589.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 - -endstream -endobj -83 0 obj -<< -/Length 6882 ->> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 57.02362 559.8236 cm +1 0 0 1 57.02362 375.8236 cm q q 1 0 0 1 0 0 cm @@ -960,13 +1120,13 @@ Q Q Q q -1 0 0 1 57.02362 539.8236 cm +1 0 0 1 57.02362 355.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 461.0236 cm +1 0 0 1 57.02362 277.0236 cm q q 1 0 0 1 0 0 cm @@ -987,33 +1147,33 @@ Q Q Q q -1 0 0 1 57.02362 429.0236 cm +1 0 0 1 57.02362 245.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 397.8236 cm +1 0 0 1 57.02362 213.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 377.8236 cm +1 0 0 1 57.02362 193.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 359.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 (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 329.0236 cm +1 0 0 1 57.02362 145.0236 cm q q 1 0 0 1 0 0 cm @@ -1034,19 +1194,19 @@ Q Q Q q -1 0 0 1 57.02362 309.0236 cm +1 0 0 1 57.02362 125.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 303.0236 cm +1 0 0 1 57.02362 119.0236 cm Q q -1 0 0 1 57.02362 303.0236 cm +1 0 0 1 57.02362 119.0236 cm Q q -1 0 0 1 57.02362 291.0236 cm +1 0 0 1 57.02362 107.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1069,10 +1229,10 @@ Q Q Q q -1 0 0 1 57.02362 285.0236 cm +1 0 0 1 57.02362 101.0236 cm Q q -1 0 0 1 57.02362 273.0236 cm +1 0 0 1 57.02362 89.02362 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1094,10 +1254,10 @@ Q Q Q q -1 0 0 1 57.02362 267.0236 cm +1 0 0 1 57.02362 83.02362 cm Q q -1 0 0 1 57.02362 255.0236 cm +1 0 0 1 57.02362 71.02362 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1119,10 +1279,19 @@ Q Q Q q -1 0 0 1 57.02362 249.0236 cm +1 0 0 1 57.02362 65.02362 cm Q + +endstream +endobj +93 0 obj +<< +/Length 8740 +>> +stream +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 57.02362 237.0236 cm +1 0 0 1 57.02362 753.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1145,10 +1314,10 @@ Q Q Q q -1 0 0 1 57.02362 231.0236 cm +1 0 0 1 57.02362 747.0236 cm Q q -1 0 0 1 57.02362 219.0236 cm +1 0 0 1 57.02362 735.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1171,22 +1340,22 @@ Q Q Q q -1 0 0 1 57.02362 219.0236 cm +1 0 0 1 57.02362 735.0236 cm Q q -1 0 0 1 57.02362 201.0236 cm +1 0 0 1 57.02362 717.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 195.0236 cm +1 0 0 1 57.02362 711.0236 cm Q q -1 0 0 1 57.02362 195.0236 cm +1 0 0 1 57.02362 711.0236 cm Q q -1 0 0 1 57.02362 183.0236 cm +1 0 0 1 57.02362 699.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1208,10 +1377,10 @@ Q Q Q q -1 0 0 1 57.02362 177.0236 cm +1 0 0 1 57.02362 693.0236 cm Q q -1 0 0 1 57.02362 165.0236 cm +1 0 0 1 57.02362 681.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1233,16 +1402,16 @@ Q Q Q q -1 0 0 1 57.02362 165.0236 cm +1 0 0 1 57.02362 681.0236 cm Q q -1 0 0 1 57.02362 135.0236 cm +1 0 0 1 57.02362 651.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 94.62362 cm +1 0 0 1 57.02362 610.6236 cm q q 1 0 0 1 0 0 cm @@ -1262,36 +1431,27 @@ Q Q Q Q - -endstream -endobj -84 0 obj -<< -/Length 7084 ->> -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 566.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 .330556 Tw (Scheme calls inherits this limit. The explicit frame stack removes it. uncommonlisp can recurse 50,000 deep) Tj T* 0 Tw (without difficulty, limited only by available memory.) Tj T* ET Q Q q -1 0 0 1 57.02362 697.8236 cm +1 0 0 1 57.02362 535.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 677.8236 cm +1 0 0 1 57.02362 515.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 589.4236 cm +1 0 0 1 57.02362 427.0236 cm q q 1 0 0 1 0 0 cm @@ -1312,19 +1472,19 @@ Q Q Q q -1 0 0 1 57.02362 569.4236 cm +1 0 0 1 57.02362 407.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 563.4236 cm +1 0 0 1 57.02362 401.0236 cm Q q -1 0 0 1 57.02362 563.4236 cm +1 0 0 1 57.02362 401.0236 cm Q q -1 0 0 1 57.02362 539.4236 cm +1 0 0 1 57.02362 377.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1346,10 +1506,10 @@ Q Q Q q -1 0 0 1 57.02362 533.4236 cm +1 0 0 1 57.02362 371.0236 cm Q q -1 0 0 1 57.02362 521.4236 cm +1 0 0 1 57.02362 359.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1371,10 +1531,10 @@ Q Q Q q -1 0 0 1 57.02362 515.4236 cm +1 0 0 1 57.02362 353.0236 cm Q q -1 0 0 1 57.02362 503.4236 cm +1 0 0 1 57.02362 341.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1396,10 +1556,10 @@ Q Q Q q -1 0 0 1 57.02362 497.4236 cm +1 0 0 1 57.02362 335.0236 cm Q q -1 0 0 1 57.02362 485.4236 cm +1 0 0 1 57.02362 323.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1421,10 +1581,10 @@ Q Q Q q -1 0 0 1 57.02362 479.4236 cm +1 0 0 1 57.02362 317.0236 cm Q q -1 0 0 1 57.02362 467.4236 cm +1 0 0 1 57.02362 305.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1447,23 +1607,23 @@ Q Q Q q -1 0 0 1 57.02362 467.4236 cm +1 0 0 1 57.02362 305.0236 cm Q q -1 0 0 1 57.02362 449.4236 cm +1 0 0 1 57.02362 287.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 443.4236 cm +1 0 0 1 57.02362 281.0236 cm Q q -1 0 0 1 57.02362 443.4236 cm +1 0 0 1 57.02362 281.0236 cm Q q -1 0 0 1 57.02362 431.4236 cm +1 0 0 1 57.02362 269.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1485,10 +1645,10 @@ Q Q Q q -1 0 0 1 57.02362 425.4236 cm +1 0 0 1 57.02362 263.0236 cm Q q -1 0 0 1 57.02362 413.4236 cm +1 0 0 1 57.02362 251.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1510,10 +1670,10 @@ Q Q Q q -1 0 0 1 57.02362 407.4236 cm +1 0 0 1 57.02362 245.0236 cm Q q -1 0 0 1 57.02362 395.4236 cm +1 0 0 1 57.02362 233.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1535,10 +1695,10 @@ Q Q Q q -1 0 0 1 57.02362 389.4236 cm +1 0 0 1 57.02362 227.0236 cm Q q -1 0 0 1 57.02362 377.4236 cm +1 0 0 1 57.02362 215.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1561,10 +1721,10 @@ Q Q Q q -1 0 0 1 57.02362 371.4236 cm +1 0 0 1 57.02362 209.0236 cm Q q -1 0 0 1 57.02362 359.4236 cm +1 0 0 1 57.02362 197.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1587,28 +1747,28 @@ Q Q Q q -1 0 0 1 57.02362 359.4236 cm +1 0 0 1 57.02362 197.0236 cm Q q -1 0 0 1 57.02362 317.4236 cm +1 0 0 1 57.02362 155.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 291.4236 cm +1 0 0 1 57.02362 129.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 273.4236 cm +1 0 0 1 57.02362 111.0236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (A generator in uncommonlisp 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 89.02362 cm +1 0 0 1 57.02362 70.62362 cm q q 1 0 0 1 0 0 cm @@ -1618,10 +1778,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 31.2 re B* Q q -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 +BT 1 0 0 1 0 11.2 Tm 9.6 TL /F5 8 Tf 0 0 0 rg (\(auto-compile! #t\)) Tj T* (\(define \(make-gen thunk\)) Tj T* ET Q Q Q @@ -1630,39 +1790,59 @@ Q endstream endobj -85 0 obj +94 0 obj << -/Length 9324 +/Length 8781 >> 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 +1 0 0 1 57.02362 607.8236 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 156 re B* +Q +q +BT 1 0 0 1 0 136 Tm 9.6 TL /F5 8 Tf 0 0 0 rg ( \(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 575.8236 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 715.0236 cm +1 0 0 1 57.02362 549.8236 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 697.0236 cm +1 0 0 1 57.02362 531.8236 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 691.0236 cm +1 0 0 1 57.02362 525.8236 cm Q q -1 0 0 1 57.02362 691.0236 cm +1 0 0 1 57.02362 525.8236 cm Q q -1 0 0 1 57.02362 679.0236 cm +1 0 0 1 57.02362 513.8236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1684,10 +1864,10 @@ Q Q Q q -1 0 0 1 57.02362 673.0236 cm +1 0 0 1 57.02362 507.8236 cm Q q -1 0 0 1 57.02362 661.0236 cm +1 0 0 1 57.02362 495.8236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1709,112 +1889,6 @@ Q Q Q q -1 0 0 1 57.02362 655.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 -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 (Exception) Tj /F1 10 Tf (: ) Tj /F5 10 Tf (call/cc) Tj /F1 10 Tf ( feeds control to a handler registered via ) Tj /F5 10 Tf (dynamic-wind) Tj T* ET -Q -Q -q -Q -Q -Q -q -1 0 0 1 57.02362 637.0236 cm -Q -q -1 0 0 1 57.02362 625.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 (Checkpoint) Tj /F1 10 Tf (: portal serializes the continuation to JSON, feeds the machine state to storage) Tj T* ET -Q -Q -q -Q -Q -Q -q -1 0 0 1 57.02362 619.0236 cm -Q -q -1 0 0 1 57.02362 607.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 (Migration) Tj /F1 10 Tf (: portal deserializes on another machine, feeds the continuation back to a new VM) Tj T* ET -Q -Q -q -Q -Q -Q -q -1 0 0 1 57.02362 589.0236 cm -Q -q -1 0 0 1 57.02362 571.0236 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 539.8236 cm -q -BT 1 0 0 1 0 2.2 Tm 13.2 TL /F2 11 Tf .133333 .133333 .133333 rg (5. Optimizations) Tj T* ET -Q -Q -q -1 0 0 1 57.02362 513.8236 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (5.1 Peephole Optimizer) Tj T* ET -Q -Q -q -1 0 0 1 57.02362 495.8236 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj /F5 10 Tf (_peephole) Tj /F1 10 Tf ( function runs over every compiled procedure after bytecode generation:) Tj T* ET -Q -Q -q -1 0 0 1 57.02362 489.8236 cm -Q -q 1 0 0 1 57.02362 489.8236 cm Q q @@ -1832,7 +1906,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 (Dead code elimination) Tj /F1 10 Tf (: ) Tj /F5 10 Tf (OP_VOID) Tj /F1 10 Tf ( followed by ) Tj /F5 10 Tf (OP_POP) Tj /F1 10 Tf ( ) Tj /F6 10 Tf 12 TL (\256) Tj /F1 10 Tf 12 TL ( remove both instructions) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (Exception) Tj /F1 10 Tf (: ) Tj /F5 10 Tf (call/cc) Tj /F1 10 Tf ( feeds control to a handler registered via ) Tj /F5 10 Tf (dynamic-wind) Tj T* ET Q Q q @@ -1857,7 +1931,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 (Redundant jump elimination) Tj /F1 10 Tf (: ) Tj /F5 10 Tf (OP_JUMP) Tj /F1 10 Tf ( to the next instruction ) Tj /F6 10 Tf 12 TL (\256) Tj /F1 10 Tf 12 TL ( remove the jump) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (Checkpoint) Tj /F1 10 Tf (: portal serializes the continuation, feeds the machine state to storage) Tj T* ET Q Q q @@ -1882,7 +1956,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 (Jump target adjustment) Tj /F1 10 Tf (: After removing instructions, all jump offsets update to maintain correctness) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (Migration) Tj /F1 10 Tf (: portal deserializes on another machine, feeds the continuation back to a new VM) Tj T* ET Q Q q @@ -1907,7 +1981,7 @@ Q q 1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 14 Tm .441529 Tw 12 TL /F3 10 Tf 0 0 0 rg (Source map preservation) Tj /F1 10 Tf (: The parallel source map \(line numbers per instruction\) stays synchronized) Tj T* 0 Tw (after removals) Tj T* ET +BT 1 0 0 1 0 14 Tm .138835 Tw 12 TL /F3 10 Tf 0 0 0 rg (Cross-impl exchange) Tj /F1 10 Tf (: S-expression serialization feeds bindings across implementations that share no) Tj T* 0 Tw (memory layout) Tj T* ET Q Q q @@ -1918,31 +1992,347 @@ q 1 0 0 1 57.02362 393.8236 cm Q q -1 0 0 1 57.02362 367.8236 cm +1 0 0 1 57.02362 375.8236 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 349.8236 cm +q +BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (4.3 Three Scopes of Feedback) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 331.8236 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The single word "feedback" covers three nested scopes, each giving rise to one of our core abstractions:) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 325.8236 cm +Q +q +1 0 0 1 57.02362 253.8236 cm +q +1 1 1 rg +n 0 72 481.2283 -18 re f* +.878431 .878431 .878431 rg +n 0 54 481.2283 -18 re f* +1 1 1 rg +n 0 36 481.2283 -18 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 57 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 22.30555 0 Td (Scope) Tj T* -22.30555 0 Td ET +Q +Q +q +1 0 0 1 92.6211 57 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 34.14197 0 Td (Mechanism) Tj T* -34.14197 0 Td ET +Q +Q +q +1 0 0 1 227.365 57 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 30.81197 0 Td (Unit of travel) Tj T* -30.81197 0 Td ET +Q +Q +q +1 0 0 1 362.109 57 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 19.60969 0 Td (Implementation) Tj T* -19.60969 0 Td ET +Q +Q +0 0 0 rg +BT /F1 10 Tf 12 TL ET +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 (Within process) Tj T* ET +Q +Q +q +1 0 0 1 92.6211 39 cm +q +BT 1 0 0 1 0 2 Tm 12 TL /F5 10 Tf 0 0 0 rg (call/cc) Tj /F1 10 Tf (, tail-call) Tj T* ET +Q +Q +q +1 0 0 1 227.365 39 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (continuation \(live\)) Tj T* ET +Q +Q +q +1 0 0 1 362.109 39 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (explicit frame stack) Tj T* ET +Q +Q +q +1 0 0 1 6 21 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Across process) Tj T* ET +Q +Q +q +1 0 0 1 92.6211 21 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (portal \(JSON or binary\)) Tj T* ET +Q +Q +q +1 0 0 1 227.365 21 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (VM state + continuation) Tj T* ET +Q +Q +q +1 0 0 1 362.109 21 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (graph serializer) Tj T* ET +Q +Q +q +1 0 0 1 6 3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Across impl) Tj T* ET +Q +Q +q +1 0 0 1 92.6211 3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (source-as-interchange) Tj T* ET +Q +Q +q +1 0 0 1 227.365 3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (bindings \(as data\)) Tj T* ET +Q +Q +q +1 0 0 1 362.109 3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (the reader) Tj T* ET +Q +Q +q +1 J +1 j +0 0 0 RG +.25 w +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 86.6211 0 m 86.6211 72 l S +n 221.365 0 m 221.365 72 l S +n 356.109 0 m 356.109 72 l S +n 0 72 m 481.2283 72 l S +n 0 0 m 481.2283 0 l S +n 0 0 m 0 72 l S +n 481.2283 0 m 481.2283 72 l S +Q +Q +Q +q +1 0 0 1 57.02362 253.8236 cm +Q +q +1 0 0 1 57.02362 199.8236 cm +q +BT 1 0 0 1 0 38 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 /F5 10 Tf (\(define) Tj ( ) Tj (x) Tj ( ) Tj (42\)) Tj /F1 10 Tf ( travels because every parser already knows how to receive it.) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 169.8236 cm +q +0 0 0 rg +BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .148334 Tw (The same abstraction, at three scopes. No new primitive at any level. This is what "feedback is all you need") Tj T* 0 Tw (actually means once you extend it past the process boundary.) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 138.6236 cm +q +BT 1 0 0 1 0 2.2 Tm 13.2 TL /F2 11 Tf .133333 .133333 .133333 rg (5. Optimizations) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 112.6236 cm +q +BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (5.1 Peephole Optimizer) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 94.62362 cm +q +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj /F5 10 Tf (_peephole) Tj /F1 10 Tf ( function runs over every compiled procedure after bytecode generation:) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 88.62362 cm +Q +q +1 0 0 1 57.02362 88.62362 cm +Q +q +1 0 0 1 57.02362 76.62362 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 (Dead code elimination) Tj /F1 10 Tf (: ) Tj /F5 10 Tf (OP_VOID) Tj /F1 10 Tf ( followed by ) Tj /F5 10 Tf (OP_POP) Tj /F1 10 Tf ( ) Tj /F6 10 Tf 12 TL (\256) Tj /F1 10 Tf 12 TL ( remove both instructions) Tj T* ET +Q +Q +q +Q +Q +Q +q +1 0 0 1 57.02362 70.62362 cm +Q + +endstream +endobj +95 0 obj +<< +/Length 11752 +>> +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 +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 (Redundant jump elimination) Tj /F1 10 Tf (: ) Tj /F5 10 Tf (OP_JUMP) Tj /F1 10 Tf ( to the next instruction ) Tj /F6 10 Tf 12 TL (\256) Tj /F1 10 Tf 12 TL ( remove the jump) Tj T* ET +Q +Q +q +Q +Q +Q +q +1 0 0 1 57.02362 747.0236 cm +Q +q +1 0 0 1 57.02362 735.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 (Jump target adjustment) Tj /F1 10 Tf (: After removing instructions, all jump offsets update to maintain correctness) Tj T* ET +Q +Q +q +Q +Q +Q +q +1 0 0 1 57.02362 729.0236 cm +Q +q +1 0 0 1 57.02362 705.0236 cm +q +0 0 0 rg +BT /F1 10 Tf 12 TL ET +q +1 0 0 1 6 9 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 .441529 Tw 12 TL /F3 10 Tf 0 0 0 rg (Source map preservation) Tj /F1 10 Tf (: The parallel source map \(line numbers per instruction\) stays synchronized) Tj T* 0 Tw (after removals) Tj T* ET +Q +Q +q +Q +Q +Q +q +1 0 0 1 57.02362 687.0236 cm +Q +q +1 0 0 1 57.02362 661.0236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (5.2 Inline Cache) Tj T* ET Q Q q -1 0 0 1 57.02362 325.8236 cm +1 0 0 1 57.02362 619.0236 cm q BT 1 0 0 1 0 26 Tm 1.884556 Tw 12 TL /F1 10 Tf 0 0 0 rg (Variable lookup in a chain of lexical environments requires walking from the current environment to the) Tj T* 0 Tw 2.510642 Tw (global. For frequently accessed global variables \(builtins like ) Tj /F5 10 Tf (+) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (car) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (null?) Tj /F1 10 Tf (\), this traversal dominates) Tj T* 0 Tw (execution time.) Tj T* ET Q Q q -1 0 0 1 57.02362 295.8236 cm +1 0 0 1 57.02362 589.0236 cm q BT 1 0 0 1 0 14 Tm 5.885372 Tw 12 TL /F1 10 Tf 0 0 0 rg (The inline cache tracks ) Tj /F5 10 Tf (instruction_index) Tj ( ) Tj /F6 10 Tf 12 TL (\256) Tj /F5 10 Tf 12 TL ( ) Tj (\(cached_env,) Tj ( ) Tj (cached_value\)) Tj /F1 10 Tf ( pairs. On) Tj T* 0 Tw /F5 10 Tf (OP_LOOKUP) Tj /F1 10 Tf (:) Tj T* ET Q Q q -1 0 0 1 57.02362 289.8236 cm +1 0 0 1 57.02362 583.0236 cm Q q -1 0 0 1 57.02362 289.8236 cm +1 0 0 1 57.02362 583.0236 cm Q q -1 0 0 1 57.02362 277.8236 cm +1 0 0 1 57.02362 571.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1965,10 +2355,10 @@ Q Q Q q -1 0 0 1 57.02362 271.8236 cm +1 0 0 1 57.02362 565.0236 cm Q q -1 0 0 1 57.02362 259.8236 cm +1 0 0 1 57.02362 553.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -1991,10 +2381,10 @@ Q Q Q q -1 0 0 1 57.02362 253.8236 cm +1 0 0 1 57.02362 547.0236 cm Q q -1 0 0 1 57.02362 241.8236 cm +1 0 0 1 57.02362 535.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -2017,10 +2407,10 @@ Q Q Q q -1 0 0 1 57.02362 235.8236 cm +1 0 0 1 57.02362 529.0236 cm Q q -1 0 0 1 57.02362 223.8236 cm +1 0 0 1 57.02362 517.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -2042,30 +2432,30 @@ Q Q Q q -1 0 0 1 57.02362 223.8236 cm +1 0 0 1 57.02362 517.0236 cm Q q -1 0 0 1 57.02362 193.8236 cm +1 0 0 1 57.02362 487.0236 cm q 0 0 0 rg BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .747025 Tw (This optimization targets the common case: inner loops that reference global functions thousands of times.) Tj T* 0 Tw (The cache stays valid as long as the binding is not shadowed locally.) Tj T* ET Q Q q -1 0 0 1 57.02362 167.8236 cm +1 0 0 1 57.02362 461.0236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (5.3 Constant Folding) Tj T* ET Q Q q -1 0 0 1 57.02362 149.8236 cm +1 0 0 1 57.02362 443.0236 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The compiler evaluates pure expressions at compile time:) Tj T* ET Q Q q -1 0 0 1 57.02362 99.82362 cm +1 0 0 1 57.02362 393.0236 cm q q 1 0 0 1 0 0 cm @@ -2085,55 +2475,42 @@ Q Q Q q -1 0 0 1 57.02362 67.82362 cm +1 0 0 1 57.02362 361.0236 cm q BT 1 0 0 1 0 14 Tm .949897 Tw 12 TL /F1 10 Tf 0 0 0 rg (Supported foldable operations: ) Tj /F5 10 Tf (+) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (-) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (*) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (=) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (<) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (>) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (<) Tj (=) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (>) Tj (=) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (not) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (zero?) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (positive?) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (negative?) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (abs) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (min) Tj /F1 10 Tf (,) Tj T* 0 Tw /F5 10 Tf (max) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (string-length) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (string-append) Tj /F1 10 Tf (.) Tj T* ET Q Q - -endstream -endobj -86 0 obj -<< -/Length 12432 ->> -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 +1 0 0 1 57.02362 331.0236 cm q BT 1 0 0 1 0 14 Tm .584272 Tw 12 TL /F1 10 Tf 0 0 0 rg (Folding only applies when all operands are compile-time constants & the function name is not shadowed in) Tj T* 0 Tw (the compilation environment.) Tj T* ET Q Q q -1 0 0 1 57.02362 709.8236 cm +1 0 0 1 57.02362 299.8236 cm q BT 1 0 0 1 0 2.2 Tm 13.2 TL /F2 11 Tf .133333 .133333 .133333 rg (6. Benchmarks: Three Evaluators vs CPython) Tj T* ET Q Q q -1 0 0 1 57.02362 677.8236 cm +1 0 0 1 57.02362 267.8236 cm q BT 1 0 0 1 0 14 Tm 3.500642 Tw 12 TL /F1 10 Tf 0 0 0 rg (All benchmarks run on the same machine, same Python 3 interpreter. Three columns: tree-walking) Tj T* 0 Tw (interpreter \() Tj /F5 10 Tf (leval) Tj /F1 10 Tf (\), bytecode VM \() Tj /F5 10 Tf (--fast) Tj /F1 10 Tf (\), & equivalent CPython. Times are best-of-3 in milliseconds.) Tj T* ET Q Q q -1 0 0 1 57.02362 651.8236 cm +1 0 0 1 57.02362 241.8236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (6.1 Raw Results) Tj T* ET Q Q q -1 0 0 1 57.02362 639.8236 cm +1 0 0 1 57.02362 229.8236 cm Q q -1 0 0 1 57.02362 441.8236 cm +1 0 0 1 57.02362 67.82362 cm q 1 1 1 rg -n 0 198 481.2283 -18 re f* -.878431 .878431 .878431 rg -n 0 180 481.2283 -18 re f* -1 1 1 rg n 0 162 481.2283 -18 re f* .878431 .878431 .878431 rg n 0 144 481.2283 -18 re f* @@ -2154,35 +2531,35 @@ 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 183 cm +1 0 0 1 6 147 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 46.97472 0 Td (Benchmark) Tj T* -46.97472 0 Td ET Q Q q -1 0 0 1 166.4094 183 cm +1 0 0 1 166.4094 147 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 11.59736 0 Td (Interp ms) Tj T* -11.59736 0 Td ET Q Q q -1 0 0 1 246.6142 183 cm +1 0 0 1 246.6142 147 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 18.26736 0 Td (BC ms) Tj T* -18.26736 0 Td ET Q Q q -1 0 0 1 326.8189 183 cm +1 0 0 1 326.8189 147 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 19.37236 0 Td (Py ms) Tj T* -19.37236 0 Td ET Q Q q -1 0 0 1 407.0236 183 cm +1 0 0 1 407.0236 147 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 4.377362 0 Td (BC Speedup) Tj T* -4.377362 0 Td ET @@ -2191,262 +2568,192 @@ Q 0 0 0 rg BT /F1 10 Tf 12 TL ET q -1 0 0 1 6 165 cm +1 0 0 1 6 129 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (fib\(35\) iterative \(named-let\)) Tj T* ET Q Q q -1 0 0 1 166.4094 165 cm +1 0 0 1 166.4094 129 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (2.2) Tj T* ET Q Q q -1 0 0 1 246.6142 165 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.5) Tj T* ET -Q -Q -q -1 0 0 1 326.8189 165 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.0) Tj T* ET -Q -Q -q -1 0 0 1 407.0236 165 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (4.4x) Tj T* ET -Q -Q -q -1 0 0 1 6 147 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (fib\(20\) tree-recursive) Tj T* ET -Q -Q -q -1 0 0 1 166.4094 147 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (1336.3) Tj T* ET -Q -Q -q -1 0 0 1 246.6142 147 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (144.8) Tj T* ET -Q -Q -q -1 0 0 1 326.8189 147 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (1.7) Tj T* ET -Q -Q -q -1 0 0 1 407.0236 147 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (9.2x) Tj T* ET -Q -Q -q -1 0 0 1 6 129 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (tak\(15,10,6\)) Tj T* ET -Q -Q -q -1 0 0 1 166.4094 129 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (125.7) Tj T* ET -Q -Q -q 1 0 0 1 246.6142 129 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (16.1) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.5) Tj T* ET Q Q q 1 0 0 1 326.8189 129 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.3) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.0) Tj T* ET Q Q q 1 0 0 1 407.0236 129 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (7.8x) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (4.4x) Tj T* ET Q Q q 1 0 0 1 6 111 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (sum-to\(50000\) tail-recursive) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (fib\(20\) tree-recursive) Tj T* ET Q Q q 1 0 0 1 166.4094 111 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (3475.3) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (1336.3) Tj T* ET Q Q q 1 0 0 1 246.6142 111 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (303.6) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (144.8) Tj T* ET Q Q q 1 0 0 1 326.8189 111 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (3.4) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (1.7) Tj T* ET Q Q q 1 0 0 1 407.0236 111 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (11.4x) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (9.2x) Tj T* ET Q Q q 1 0 0 1 6 93 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (list ops \(5000 elements\)) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (tak\(15,10,6\)) Tj T* ET Q Q q 1 0 0 1 166.4094 93 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (52.6) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (125.7) Tj T* ET Q Q q 1 0 0 1 246.6142 93 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (4.4) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (16.1) Tj T* ET Q Q q 1 0 0 1 326.8189 93 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.5) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.3) Tj T* ET Q Q q 1 0 0 1 407.0236 93 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (12.0x) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (7.8x) Tj T* ET Q Q q 1 0 0 1 6 75 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (closure factory \(100 adders\)) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (sum-to\(50000\) tail-recursive) Tj T* ET Q Q q 1 0 0 1 166.4094 75 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (4.4) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (3475.3) Tj T* ET Q Q q 1 0 0 1 246.6142 75 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (\227) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (303.6) Tj T* ET Q Q q 1 0 0 1 326.8189 75 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.1) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (3.4) Tj T* ET Q Q q 1 0 0 1 407.0236 75 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (\227) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (11.4x) Tj T* ET Q Q 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 (hash-table \(1000 set+ref\)) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (list ops \(5000 elements\)) Tj T* ET Q Q q 1 0 0 1 166.4094 57 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (135.1) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (52.6) Tj T* ET Q Q q 1 0 0 1 246.6142 57 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (84.6) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (4.4) Tj T* ET Q Q q 1 0 0 1 326.8189 57 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.4) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.5) Tj T* ET Q Q q 1 0 0 1 407.0236 57 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (1.6x) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (12.0x) 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 (string-join \(200 numbers\)) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (closure factory \(100 adders\)) Tj T* ET Q Q q 1 0 0 1 166.4094 39 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.6) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (4.4) Tj T* ET Q Q q @@ -2460,7 +2767,7 @@ q 1 0 0 1 326.8189 39 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.0) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.1) Tj T* ET Q Q q @@ -2474,6 +2781,118 @@ q 1 0 0 1 6 21 cm q 0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (hash-table \(1000 set+ref\)) Tj T* ET +Q +Q +q +1 0 0 1 166.4094 21 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (135.1) Tj T* ET +Q +Q +q +1 0 0 1 246.6142 21 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (84.6) Tj T* ET +Q +Q +q +1 0 0 1 326.8189 21 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.4) Tj T* ET +Q +Q +q +1 0 0 1 407.0236 21 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (1.6x) Tj T* ET +Q +Q +q +1 0 0 1 6 3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (string-join \(200 numbers\)) Tj T* ET +Q +Q +q +1 0 0 1 166.4094 3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.6) Tj T* ET +Q +Q +q +1 0 0 1 246.6142 3 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 326.8189 3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.0) Tj T* ET +Q +Q +q +1 0 0 1 407.0236 3 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 J +1 j +0 0 0 RG +.25 w +n 0 0 m 481.2283 0 l S +n 0 144 m 481.2283 144 l S +n 0 126 m 481.2283 126 l S +n 0 108 m 481.2283 108 l S +n 0 90 m 481.2283 90 l S +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 160.4094 0 m 160.4094 162 l S +n 240.6142 0 m 240.6142 162 l S +n 320.8189 0 m 320.8189 162 l S +n 401.0236 0 m 401.0236 162 l S +n 0 162 m 481.2283 162 l S +n 0 0 m 0 162 l S +n 481.2283 0 m 481.2283 162 l S +Q +Q +Q + +endstream +endobj +96 0 obj +<< +/Length 11262 +>> +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 +q +1 1 1 rg +n 0 36 481.2283 -18 re f* +.878431 .878431 .878431 rg +n 0 18 481.2283 -18 re f* +0 0 0 rg +BT /F1 10 Tf 12 TL ET +q +1 0 0 1 6 21 cm +q +0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (ackermann\(3,4\)) Tj T* ET Q Q @@ -2545,82 +2964,73 @@ q 1 j 0 0 0 RG .25 w -n 0 180 m 481.2283 180 l S -n 0 162 m 481.2283 162 l S -n 0 144 m 481.2283 144 l S -n 0 126 m 481.2283 126 l S -n 0 108 m 481.2283 108 l S -n 0 90 m 481.2283 90 l S -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 160.4094 0 m 160.4094 198 l S -n 240.6142 0 m 240.6142 198 l S -n 320.8189 0 m 320.8189 198 l S -n 401.0236 0 m 401.0236 198 l S -n 0 198 m 481.2283 198 l S +n 160.4094 0 m 160.4094 36 l S +n 240.6142 0 m 240.6142 36 l S +n 320.8189 0 m 320.8189 36 l S +n 401.0236 0 m 401.0236 36 l S +n 0 0 m 0 36 l S +n 481.2283 0 m 481.2283 36 l S n 0 0 m 481.2283 0 l S -n 0 0 m 0 198 l S -n 481.2283 0 m 481.2283 198 l S Q Q Q q -1 0 0 1 57.02362 441.8236 cm +1 0 0 1 57.02362 729.0236 cm Q q -1 0 0 1 57.02362 411.8236 cm +1 0 0 1 57.02362 699.0236 cm q BT 1 0 0 1 0 14 Tm 4.184882 Tw 12 TL /F3 10 Tf 0 0 0 rg (BC Speedup) Tj /F1 10 Tf ( = interpreter time / bytecode time. This measures the gain from compilation within) Tj T* 0 Tw (uncommonlisp itself.) Tj T* ET Q Q q -1 0 0 1 57.02362 385.8236 cm +1 0 0 1 57.02362 673.0236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (6.2 Analysis) Tj T* ET Q Q q -1 0 0 1 57.02362 331.8236 cm +1 0 0 1 57.02362 619.0236 cm q BT 1 0 0 1 0 38 Tm 2.646027 Tw 12 TL /F1 10 Tf 0 0 0 rg (The bytecode compiler delivers ) Tj /F3 10 Tf (7--12x speedups) Tj /F1 10 Tf ( on recursive & iterative workloads compared to the) Tj T* 0 Tw .139168 Tw (tree-walking interpreter. The largest gains appear in tight loops \() Tj /F5 10 Tf (sum-to) Tj /F1 10 Tf (: 11.4x\) & deep recursion \() Tj /F5 10 Tf (fib\(20\)) Tj /F1 10 Tf T* 0 Tw .224882 Tw (tree: 9.2x, ) Tj /F5 10 Tf (mergesort) Tj /F1 10 Tf (: 11.0x\), where the explicit frame stack & specialized opcodes eliminate the overhead) Tj T* 0 Tw (of AST traversal.) Tj T* ET Q Q q -1 0 0 1 57.02362 301.8236 cm +1 0 0 1 57.02362 589.0236 cm q 0 0 0 rg BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 1.762025 Tw (Hash table operations show a smaller speedup \(1.6x\) because the bottleneck sits in Python's dictionary) Tj T* 0 Tw (operations, not in Scheme evaluation overhead.) Tj T* ET Q Q q -1 0 0 1 57.02362 247.8236 cm +1 0 0 1 57.02362 535.0236 cm q BT 1 0 0 1 0 38 Tm 1.224168 Tw 12 TL /F1 10 Tf 0 0 0 rg (CPython remains 50--150x faster than the bytecode VM on most benchmarks. This is expected: CPython) Tj T* 0 Tw .398022 Tw (compiles to native bytecode with a C runtime, while uncommonlisp's bytecode VM is itself written in Python.) Tj T* 0 Tw 1.146027 Tw (The comparison establishes that uncommonlisp pays a known, bounded overhead for running a complete) Tj T* 0 Tw (Scheme \(with full ) Tj /F5 10 Tf (call/cc) Tj /F1 10 Tf (, exact rationals, & hygienic macros\) inside a host language.) Tj T* ET Q Q q -1 0 0 1 57.02362 205.8236 cm +1 0 0 1 57.02362 493.0236 cm q 0 0 0 rg BT 1 0 0 1 0 26 Tm /F1 10 Tf 12 TL 3.278031 Tw (The important comparison is not uncommonlisp vs CPython \(different languages\), but uncommonlisp) Tj T* 0 Tw .750759 Tw (interpreter vs uncommonlisp bytecode \(same language, same semantics, different execution strategy\). The) Tj T* 0 Tw (bytecode compiler proves that feedback-based architecture does not preclude efficient execution.) Tj T* ET Q Q q -1 0 0 1 57.02362 179.8236 cm +1 0 0 1 57.02362 467.0236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (6.3 What the Benchmarks Test) Tj T* ET Q Q q -1 0 0 1 57.02362 167.8236 cm +1 0 0 1 57.02362 455.0236 cm Q q -1 0 0 1 57.02362 167.8236 cm +1 0 0 1 57.02362 455.0236 cm Q q -1 0 0 1 57.02362 155.8236 cm +1 0 0 1 57.02362 443.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -2642,10 +3052,10 @@ Q Q Q q -1 0 0 1 57.02362 149.8236 cm +1 0 0 1 57.02362 437.0236 cm Q q -1 0 0 1 57.02362 137.8236 cm +1 0 0 1 57.02362 425.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -2667,10 +3077,10 @@ Q Q Q q -1 0 0 1 57.02362 131.8236 cm +1 0 0 1 57.02362 419.0236 cm Q q -1 0 0 1 57.02362 119.8236 cm +1 0 0 1 57.02362 407.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -2692,10 +3102,10 @@ Q Q Q q -1 0 0 1 57.02362 113.8236 cm +1 0 0 1 57.02362 401.0236 cm Q q -1 0 0 1 57.02362 101.8236 cm +1 0 0 1 57.02362 389.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -2717,10 +3127,10 @@ Q Q Q q -1 0 0 1 57.02362 95.82362 cm +1 0 0 1 57.02362 383.0236 cm Q q -1 0 0 1 57.02362 83.82362 cm +1 0 0 1 57.02362 371.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -2742,10 +3152,10 @@ Q Q Q q -1 0 0 1 57.02362 77.82362 cm +1 0 0 1 57.02362 365.0236 cm Q q -1 0 0 1 57.02362 65.82362 cm +1 0 0 1 57.02362 353.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -2767,19 +3177,10 @@ Q Q Q q -1 0 0 1 57.02362 62.69291 cm +1 0 0 1 57.02362 347.0236 cm Q - -endstream -endobj -87 0 obj -<< -/Length 7218 ->> -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 335.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -2801,10 +3202,10 @@ Q Q Q q -1 0 0 1 57.02362 747.0236 cm +1 0 0 1 57.02362 329.0236 cm Q q -1 0 0 1 57.02362 735.0236 cm +1 0 0 1 57.02362 317.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -2826,40 +3227,497 @@ Q Q Q q -1 0 0 1 57.02362 717.0236 cm +1 0 0 1 57.02362 299.0236 cm Q q -1 0 0 1 57.02362 685.8236 cm +1 0 0 1 57.02362 267.8236 cm q -BT 1 0 0 1 0 2.2 Tm 13.2 TL /F2 11 Tf .133333 .133333 .133333 rg (7. Portal: Machine State Serialization) Tj T* ET +BT 1 0 0 1 0 2.2 Tm 13.2 TL /F2 11 Tf .133333 .133333 .133333 rg (7. Portal: Feedback Across Time) Tj T* ET Q Q q -1 0 0 1 57.02362 653.8236 cm +1 0 0 1 57.02362 223.8236 cm q -BT 1 0 0 1 0 14 Tm .549873 Tw 12 TL /F1 10 Tf 0 0 0 rg (Portal serializes the complete VM state \(environment, continuation stack, instruction pointer, value stack\) to) Tj T* 0 Tw (JSON & resumes execution on another machine.) Tj T* ET +BT 1 0 0 1 0 26 Tm .17989 Tw 12 TL /F1 10 Tf 0 0 0 rg (A continuation is feedback within a process. A portal is feedback across processes. Same primitive, different) Tj T* 0 Tw 1.747565 Tw (scope: capture machine state, serialize it, reload it elsewhere, resume. uncommonlisp ships three portal) Tj T* 0 Tw (formats with different tradeoffs & constituencies.) Tj T* ET Q Q q -1 0 0 1 57.02362 627.8236 cm +1 0 0 1 57.02362 217.8236 cm +Q q -BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (7.1 Serialization) Tj T* ET +1 0 0 1 57.02362 121.8236 cm +q +1 1 1 rg +n 0 96 481.2283 -18 re f* +.878431 .878431 .878431 rg +n 0 78 481.2283 -30 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 81 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 29.99012 0 Td (Format) Tj T* -29.99012 0 Td ET Q Q q -1 0 0 1 57.02362 609.8236 cm +1 0 0 1 111.8702 81 cm q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj /F5 10 Tf (_PortalSerializer) Tj /F1 10 Tf ( performs graph-aware serialization:) Tj T* ET +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 19.43012 0 Td (Consumers) Tj T* -19.43012 0 Td ET Q Q q -1 0 0 1 57.02362 603.8236 cm +1 0 0 1 217.7405 81 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 17.68098 0 Td (Size) Tj T* -17.68098 0 Td ET +Q Q q -1 0 0 1 57.02362 603.8236 cm +1 0 0 1 285.1124 81 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 16.01098 0 Td (Save) Tj T* -16.01098 0 Td ET +Q Q q -1 0 0 1 57.02362 591.8236 cm +1 0 0 1 352.4844 81 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 15.74098 0 Td (Load) Tj T* -15.74098 0 Td ET +Q +Q +q +1 0 0 1 419.8564 81 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 5.455984 0 Td (Resumes) Tj T* -5.455984 0 Td ET +Q +Q +0 0 0 rg +BT /F1 10 Tf 12 TL ET +q +1 0 0 1 6 63 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL (S-expression) Tj T* ET +Q +Q +q +1 0 0 1 111.8702 51 cm +q +0 0 0 rg +BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL -0.012441 Tw (Python, C, asm \227 all) Tj T* 0 Tw (three) Tj T* ET +Q +Q +q +1 0 0 1 217.7405 63 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (~310 B) Tj T* ET +Q +Q +q +1 0 0 1 285.1124 63 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.9 ms) Tj T* ET +Q +Q +q +1 0 0 1 352.4844 63 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.7 ms) Tj T* ET +Q +Q +q +1 0 0 1 419.8564 63 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (bindings) Tj T* ET +Q +Q +q +1 0 0 1 6 21 cm +q +0 0 0 rg +BT 1 0 0 1 0 14 Tm /F3 10 Tf 12 TL (JSON) Tj T* (\(graph-aware\)) Tj T* ET +Q +Q +q +1 0 0 1 111.8702 33 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Python, C) Tj T* ET +Q +Q +q +1 0 0 1 217.7405 33 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (~26 KB) Tj T* ET +Q +Q +q +1 0 0 1 285.1124 33 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (3.1 ms) Tj T* ET +Q +Q +q +1 0 0 1 352.4844 33 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 419.8564 33 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (full VM + k) Tj T* ET +Q +Q +q +1 0 0 1 6 3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL (Binary heap dump) Tj T* ET +Q +Q +q +1 0 0 1 111.8702 3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (asm only) Tj T* ET +Q +Q +q +1 0 0 1 217.7405 3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (~10 KB) Tj T* ET +Q +Q +q +1 0 0 1 285.1124 3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.1 ms) Tj T* ET +Q +Q +q +1 0 0 1 352.4844 3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.1 ms) Tj T* ET +Q +Q +q +1 0 0 1 419.8564 3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (asm heap) Tj T* ET +Q +Q +q +1 J +1 j +0 0 0 RG +.25 w +n 0 78 m 481.2283 78 l S +n 0 48 m 481.2283 48 l S +n 0 18 m 481.2283 18 l S +n 105.8702 0 m 105.8702 96 l S +n 211.7405 0 m 211.7405 96 l S +n 279.1124 0 m 279.1124 96 l S +n 346.4844 0 m 346.4844 96 l S +n 413.8564 0 m 413.8564 96 l S +n 0 96 m 481.2283 96 l S +n 0 0 m 481.2283 0 l S +n 0 0 m 0 96 l S +n 481.2283 0 m 481.2283 96 l S +Q +Q +Q +q +1 0 0 1 57.02362 121.8236 cm +Q +q +1 0 0 1 57.02362 91.82362 cm +q +0 0 0 rg +BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .49713 Tw (Times measured on a 4-binding workload \(int + list + string + fib\(30\) result\) excluding process startup. "k" =) Tj T* 0 Tw (continuation.) Tj T* ET +Q +Q + +endstream +endobj +97 0 obj +<< +/Length 9300 +>> +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 +q +BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (7.1 S-Expression Portal \227 the Portable One) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 735.0236 cm +q +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (The most boring format is the most portable. An S-expression portal is a sequence of ) Tj /F5 10 Tf (define) Tj /F1 10 Tf ( forms:) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 665.8236 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 60 re B* +Q +q +0 0 0 rg +BT 1 0 0 1 0 40 Tm /F5 8 Tf 9.6 TL (;; uncommonlisp portable state) Tj T* (\(define my-int 42\)) Tj T* (\(define my-list '\(1 2 3 4 5 6 7 8 9 10\)\)) Tj T* (\(define my-str "hello world"\)) Tj T* (\(define my-result 832040\)) Tj T* ET +Q +Q +Q +Q +Q +q +1 0 0 1 57.02362 633.8236 cm +q +0 0 0 rg +BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .550522 Tw (Every Scheme implementation in the world can already read this. No schema, no decoder, no version field.) Tj T* 0 Tw (The file is a Scheme program; loading it is evaluating it.) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 579.8236 cm +q +BT 1 0 0 1 0 38 Tm .702256 Tw 12 TL /F3 10 Tf 0 0 0 rg (The key insight: the language IS the interchange format.) Tj /F1 10 Tf ( We did not design this. R. Kent Dybvig didn't.) Tj T* 0 Tw 1.188726 Tw (John McCarthy didn't. It is a structural consequence of homoiconicity: if the syntax of the language is the) Tj T* 0 Tw 5.458196 Tw (syntax of its data structures, then data serialization is language serialization. Portability across) Tj T* 0 Tw (implementations is free \227 it arrives with the parser.) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 537.8236 cm +q +BT 1 0 0 1 0 26 Tm .511772 Tw 12 TL /F1 10 Tf 0 0 0 rg (Producer side: assemble the file with ) Tj /F5 10 Tf (\(display) Tj ( ) Tj (...\)) Tj /F1 10 Tf ( & ) Tj /F5 10 Tf (\(write) Tj ( ) Tj (...\)) Tj /F1 10 Tf ( to an output port. Consumer side:) Tj T* 0 Tw 3.693453 Tw /F5 10 Tf (\(load) Tj ( ) Tj ("file.sexp"\)) Tj /F1 10 Tf (. Both sides exist in every implementation, giving us a 3\3273 matrix of valid) Tj T* 0 Tw (exchanges.) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 511.8236 cm +q +BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (7.2 Cross-Implementation Exchange Matrix) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 499.8236 cm +Q +q +1 0 0 1 57.02362 409.8236 cm +q +1 1 1 rg +n 0 90 481.2283 -18 re f* +.878431 .878431 .878431 rg +n 0 72 481.2283 -18 re f* +1 1 1 rg +n 0 54 481.2283 -18 re f* +.878431 .878431 .878431 rg +n 0 36 481.2283 -18 re f* +1 1 1 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 +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 19.19482 0 Td (Producer ) Tj /F6 10 Tf 12 TL (\256) Tj /F3 10 Tf 12 TL T* -19.19482 0 Td ET +Q +Q +q +1 0 0 1 112.9396 75 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 39.43645 0 Td (Python) Tj T* -39.43645 0 Td ET +Q +Q +q +1 0 0 1 237.7025 75 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 52.77145 0 Td (C) Tj T* -52.77145 0 Td ET +Q +Q +q +1 0 0 1 362.4654 75 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 46.37645 0 Td (asm) Tj T* -46.37645 0 Td ET +Q +Q +q +1 0 0 1 6 57 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 18.33982 0 Td (Consumer ) Tj /F6 10 Tf 12 TL (\257) Tj /F3 10 Tf 12 TL T* -18.33982 0 Td ET +Q +Q +0 0 0 rg +BT /F1 10 Tf 12 TL ET +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 (Python) Tj T* ET +Q +Q +q +1 0 0 1 112.9396 39 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL /F7 10 Tf 12 TL (3) Tj /F1 10 Tf 12 TL T* ET +Q +Q +q +1 0 0 1 237.7025 39 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL /F7 10 Tf 12 TL (3) Tj /F1 10 Tf 12 TL T* ET +Q +Q +q +1 0 0 1 362.4654 39 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL /F7 10 Tf 12 TL (3) Tj /F1 10 Tf 12 TL T* ET +Q +Q +q +1 0 0 1 6 21 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (C) Tj T* ET +Q +Q +q +1 0 0 1 112.9396 21 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL /F7 10 Tf 12 TL (3) Tj /F1 10 Tf 12 TL T* ET +Q +Q +q +1 0 0 1 237.7025 21 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL /F7 10 Tf 12 TL (3) Tj /F1 10 Tf 12 TL T* ET +Q +Q +q +1 0 0 1 362.4654 21 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL /F7 10 Tf 12 TL (3) Tj /F1 10 Tf 12 TL T* ET +Q +Q +q +1 0 0 1 6 3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (asm) Tj T* ET +Q +Q +q +1 0 0 1 112.9396 3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL /F7 10 Tf 12 TL (3) Tj /F1 10 Tf 12 TL T* ET +Q +Q +q +1 0 0 1 237.7025 3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL /F7 10 Tf 12 TL (3) Tj /F1 10 Tf 12 TL T* ET +Q +Q +q +1 0 0 1 362.4654 3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL /F7 10 Tf 12 TL (3) Tj /F1 10 Tf 12 TL T* ET +Q +Q +q +1 J +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 106.9396 0 m 106.9396 90 l S +n 231.7025 0 m 231.7025 90 l S +n 356.4654 0 m 356.4654 90 l S +n 0 90 m 481.2283 90 l S +n 0 0 m 481.2283 0 l S +n 0 0 m 0 90 l S +n 481.2283 0 m 481.2283 90 l S +Q +Q +Q +q +1 0 0 1 57.02362 409.8236 cm +Q +q +1 0 0 1 57.02362 379.8236 cm +q +BT 1 0 0 1 0 14 Tm 2.324029 Tw 12 TL /F1 10 Tf 0 0 0 rg (9 of 9. Verified by ) Tj /F5 10 Tf (tests/portal-cross-test.sh) Tj /F1 10 Tf (. Same file, same semantics, regardless of which) Tj T* 0 Tw (process produced it.) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 337.8236 cm +q +0 0 0 rg +BT 1 0 0 1 0 26 Tm /F1 10 Tf 12 TL .526019 Tw (This matters because it defeats the "version lock-in" trap. If the JSON portal were the only option, a Python) Tj T* 0 Tw 2.478453 Tw (3.15 producer could emit structures a C consumer couldn't parse. With S-expression portals, the only) Tj T* 0 Tw (dependency is a parser that handles the subset of forms in the file. Every implementation already has one.) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 311.8236 cm +q +BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (7.3 JSON Portal \227 Graph-Aware, Continuation-Preserving) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 281.8236 cm +q +BT 1 0 0 1 0 14 Tm .373453 Tw 12 TL /F1 10 Tf 0 0 0 rg (When you need to preserve shared references, cycles, closures, or a ) Tj /F4 10 Tf (live continuation) Tj /F1 10 Tf (, S-expressions aren't) Tj T* 0 Tw (enough. The JSON portal \(Python & C\) performs graph-aware serialization:) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 275.8236 cm +Q +q +1 0 0 1 57.02362 275.8236 cm +Q +q +1 0 0 1 57.02362 263.8236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -2873,7 +3731,7 @@ 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 (Tracks ) Tj /F5 10 Tf (id\(obj\)) Tj ( ) Tj /F6 10 Tf 12 TL (\256) Tj /F5 10 Tf 12 TL ( ) Tj (ref_id) Tj /F1 10 Tf ( for object identity \(handles shared references & cycles\)) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Tracks ) Tj /F5 10 Tf (id\(obj\)) Tj ( ) Tj /F6 10 Tf 12 TL (\256) Tj /F5 10 Tf 12 TL ( ) Tj (ref_id) Tj /F1 10 Tf ( for object identity \(handles shared refs & cycles\)) Tj T* ET Q Q q @@ -2881,10 +3739,10 @@ Q Q Q q -1 0 0 1 57.02362 585.8236 cm +1 0 0 1 57.02362 257.8236 cm Q q -1 0 0 1 57.02362 573.8236 cm +1 0 0 1 57.02362 245.8236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -2907,10 +3765,10 @@ Q Q Q q -1 0 0 1 57.02362 567.8236 cm +1 0 0 1 57.02362 239.8236 cm Q q -1 0 0 1 57.02362 555.8236 cm +1 0 0 1 57.02362 227.8236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -2932,10 +3790,10 @@ Q Q Q q -1 0 0 1 57.02362 549.8236 cm +1 0 0 1 57.02362 221.8236 cm Q q -1 0 0 1 57.02362 537.8236 cm +1 0 0 1 57.02362 209.8236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -2958,10 +3816,10 @@ Q Q Q q -1 0 0 1 57.02362 531.8236 cm +1 0 0 1 57.02362 203.8236 cm Q q -1 0 0 1 57.02362 519.8236 cm +1 0 0 1 57.02362 191.8236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -2984,186 +3842,22 @@ Q Q Q q -1 0 0 1 57.02362 501.8236 cm +1 0 0 1 57.02362 173.8236 cm Q q -1 0 0 1 57.02362 475.8236 cm +1 0 0 1 57.02362 143.8236 cm q -BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (7.2 Deserialization) Tj T* ET +BT 1 0 0 1 0 14 Tm 2.974168 Tw 12 TL /F1 10 Tf 0 0 0 rg (Deserialization is two-pass: shell pass creates empty object shells & assigns reference IDs, fill pass) Tj T* 0 Tw (populates pointers & values. This handles the closure-that-captures-itself pattern cleanly.) Tj T* ET Q Q q -1 0 0 1 57.02362 457.8236 cm +1 0 0 1 57.02362 101.8236 cm q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj /F5 10 Tf (_PortalDeserializer) Tj /F1 10 Tf ( performs two-pass reconstruction:) Tj T* ET +BT 1 0 0 1 0 26 Tm 4.719816 Tw 12 TL /F1 10 Tf 0 0 0 rg (During VM execution, ) Tj /F5 10 Tf (portal-checkpoint!) Tj /F1 10 Tf ( triggers at ) Tj /F5 10 Tf (OP_JUMP) Tj /F1 10 Tf ( & ) Tj /F5 10 Tf (OP_TAIL_CALL) Tj /F1 10 Tf ( instructions,) Tj T* 0 Tw 1.439168 Tw (capturing the current continuation, serializing it to a ) Tj /F5 10 Tf (.portal) Tj /F1 10 Tf ( file, & continuing. Resumption restores the) Tj T* 0 Tw (saved state & continues execution from the exact instruction where the checkpoint occurred.) Tj T* ET Q Q q -1 0 0 1 57.02362 451.8236 cm -Q -q -1 0 0 1 57.02362 451.8236 cm -Q -q -1 0 0 1 57.02362 439.8236 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 2 0 Td (1.) Tj T* -2 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 (Shell pass) Tj /F1 10 Tf (: Create empty object shells & assign reference IDs) Tj T* ET -Q -Q -q -Q -Q -Q -q -1 0 0 1 57.02362 433.8236 cm -Q -q -1 0 0 1 57.02362 421.8236 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 2 0 Td (2.) Tj T* -2 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 (Fill pass) Tj /F1 10 Tf (: Populate pointers, values, & environment chains) Tj T* ET -Q -Q -q -Q -Q -Q -q -1 0 0 1 57.02362 421.8236 cm -Q -q -1 0 0 1 57.02362 391.8236 cm -q -0 0 0 rg -BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 1.780596 Tw (This handles circular references \(e.g., a closure whose environment contains a reference to the closure) Tj T* 0 Tw (itself\).) Tj T* ET -Q -Q -q -1 0 0 1 57.02362 365.8236 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (7.3 Checkpoint & Resume) Tj T* ET -Q -Q -q -1 0 0 1 57.02362 335.8236 cm -q -BT 1 0 0 1 0 14 Tm 1.357835 Tw 12 TL /F1 10 Tf 0 0 0 rg (During VM execution, ) Tj /F5 10 Tf (portal-checkpoint!) Tj /F1 10 Tf ( triggers at ) Tj /F5 10 Tf (OP_JUMP) Tj /F1 10 Tf ( & ) Tj /F5 10 Tf (OP_TAIL_CALL) Tj /F1 10 Tf ( instructions. When) Tj T* 0 Tw (triggered:) Tj T* ET -Q -Q -q -1 0 0 1 57.02362 329.8236 cm -Q -q -1 0 0 1 57.02362 329.8236 cm -Q -q -1 0 0 1 57.02362 317.8236 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 2 0 Td (1.) Tj T* -2 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 (Capture the current continuation \(same mechanism as ) Tj /F5 10 Tf (call/cc) Tj /F1 10 Tf (\)) Tj T* ET -Q -Q -q -Q -Q -Q -q -1 0 0 1 57.02362 311.8236 cm -Q -q -1 0 0 1 57.02362 299.8236 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 2 0 Td (2.) Tj T* -2 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 (Serialize the continuation + environment to a ) Tj /F5 10 Tf (.portal) Tj /F1 10 Tf ( file) Tj T* ET -Q -Q -q -Q -Q -Q -q -1 0 0 1 57.02362 293.8236 cm -Q -q -1 0 0 1 57.02362 281.8236 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 2 0 Td (3.) Tj T* -2 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Continue execution \(or halt, depending on the use case\)) Tj T* ET -Q -Q -q -Q -Q -Q -q -1 0 0 1 57.02362 281.8236 cm -Q -q -1 0 0 1 57.02362 263.8236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Resumption:) Tj T* ET -Q -Q -q -1 0 0 1 57.02362 233.0236 cm +1 0 0 1 57.02362 71.02362 cm q q 1 0 0 1 0 0 cm @@ -3183,29 +3877,592 @@ Q Q Q Q -q -1 0 0 1 57.02362 201.0236 cm -q -BT 1 0 0 1 0 14 Tm 1.54131 Tw 12 TL /F1 10 Tf 0 0 0 rg (The VM deserializes the saved state, reconstructs the continuation, & resumes execution from the exact) Tj T* 0 Tw (instruction where the checkpoint occurred. The computation does not need to restart from the beginning.) Tj T* ET -Q -Q endstream endobj -88 0 obj +98 0 obj << -/Length 6103 +/Length 9120 >> 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 q -BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (7.4 Use Case: Distributed Primality Testing) Tj T* ET +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The computation does not need to restart from the beginning.) Tj T* ET Q Q q -1 0 0 1 57.02362 626.2236 cm +1 0 0 1 57.02362 727.0236 cm +q +BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (7.4 Binary Heap Dump \227 the Fast One) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 697.0236 cm +q +BT 1 0 0 1 0 14 Tm .755197 Tw 12 TL /F1 10 Tf 0 0 0 rg (The asm implementation ships a direct-dump portal: write the raw heap bytes, the ) Tj /F5 10 Tf (r14) Tj /F1 10 Tf ( \(env\) & ) Tj /F5 10 Tf (r15) Tj /F1 10 Tf ( \(bump) Tj T* 0 Tw (pointer\) registers, the heap base address, & a magic header. No parsing, no encoding.) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 599.0236 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 88.8 re B* +Q +q +0 0 0 rg +BT 1 0 0 1 0 68.8 Tm /F5 8 Tf 9.6 TL (bi_portal_save:) Tj T* ( # Magic | heap_size | heap_base | r14 | r15 | reserved | heap_bytes) Tj T* T* (bi_portal_resume:) Tj T* ( # Read 48-byte header, verify magic + sanity,) Tj T* ( # mmap MAP_FIXED at saved heap_base so pointers stay valid,) Tj T* ( # read heap bytes into fixed-address region,) Tj T* ( # restore r14/r15.) Tj T* ET +Q +Q +Q +Q +Q +q +1 0 0 1 57.02362 555.0236 cm +q +BT 1 0 0 1 0 26 Tm 1.387739 Tw 12 TL /F1 10 Tf 0 0 0 rg (Sub-millisecond save & resume. The MAP_FIXED trick is why it works across processes: because every) Tj T* 0 Tw 1.474556 Tw (pointer inside the heap is an absolute address, resuming at a different address would require relocation.) Tj T* 0 Tw (Mapping at the same address keeps pointers live.) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 501.0236 cm +q +BT 1 0 0 1 0 38 Tm 1.067739 Tw 12 TL /F1 10 Tf 0 0 0 rg (Constraints: same architecture, same binary layout, same process model. An asm binary portal written on) Tj T* 0 Tw .022545 Tw (one box resumes on another x86_64 Linux box running the same asm binary. It does not resume on a rebuilt) Tj T* 0 Tw 1.065522 Tw (binary \227 the BSS-resident symbol table ) Tj /F5 10 Tf (sym_table) Tj /F1 10 Tf ( is not in the heap dump, so interned symbols would) Tj T* 0 Tw (need to be reinterned. That's the price of trivial serialization.) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 475.0236 cm +q +BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (7.5 Cross-Process Benchmarks) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 445.0236 cm +q +0 0 0 rg +BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 2.703647 Tw (Producer process A saves state to a file; consumer process B starts fresh, loads the file, continues.) Tj T* 0 Tw (Wall-clock time for both processes end-to-end, 50 iterations, same-laptop:) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 439.0236 cm +Q +q +1 0 0 1 57.02362 241.0236 cm +q +1 1 1 rg +n 0 198 481.2283 -18 re f* +.878431 .878431 .878431 rg +n 0 180 481.2283 -18 re f* +1 1 1 rg +n 0 162 481.2283 -18 re f* +.878431 .878431 .878431 rg +n 0 144 481.2283 -18 re f* +1 1 1 rg +n 0 126 481.2283 -18 re f* +.878431 .878431 .878431 rg +n 0 108 481.2283 -18 re f* +1 1 1 rg +n 0 90 481.2283 -18 re f* +.878431 .878431 .878431 rg +n 0 72 481.2283 -18 re f* +1 1 1 rg +n 0 54 481.2283 -18 re f* +.878431 .878431 .878431 rg +n 0 36 481.2283 -18 re f* +1 1 1 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 183 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 93.12904 0 Td (Pair \(producer ) Tj /F6 10 Tf 12 TL (\256) Tj /F3 10 Tf 12 TL ( consumer\)) Tj T* -93.12904 0 Td ET +Q +Q +q +1 0 0 1 339.1581 183 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 47.19513 0 Td (Time/iter) Tj T* -47.19513 0 Td ET +Q +Q +0 0 0 rg +BT /F1 10 Tf 12 TL ET +q +1 0 0 1 6 165 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Python ) Tj /F6 10 Tf 12 TL (\256) Tj /F1 10 Tf 12 TL ( Python \(sexp\)) Tj T* ET +Q +Q +q +1 0 0 1 339.1581 165 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (260 ms) Tj T* ET +Q +Q +q +1 0 0 1 6 147 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (C ) Tj /F6 10 Tf 12 TL (\256) Tj /F1 10 Tf 12 TL ( C \(sexp\)) Tj T* ET +Q +Q +q +1 0 0 1 339.1581 147 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (6 ms) Tj T* ET +Q +Q +q +1 0 0 1 6 129 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL (asm ) Tj /F6 10 Tf 12 TL (\256) Tj /F3 10 Tf 12 TL ( asm \(sexp\)) Tj T* ET +Q +Q +q +1 0 0 1 339.1581 129 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL (1.6 ms) Tj T* ET +Q +Q +q +1 0 0 1 6 111 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL (asm ) Tj /F6 10 Tf 12 TL (\256) Tj /F3 10 Tf 12 TL ( asm \(binary portal\)) Tj T* ET +Q +Q +q +1 0 0 1 339.1581 111 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL (1.5 ms) Tj T* ET +Q +Q +q +1 0 0 1 6 93 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Python ) Tj /F6 10 Tf 12 TL (\256) Tj /F1 10 Tf 12 TL ( C \(sexp\)) Tj T* ET +Q +Q +q +1 0 0 1 339.1581 93 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (133 ms) Tj T* ET +Q +Q +q +1 0 0 1 6 75 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Python ) Tj /F6 10 Tf 12 TL (\256) Tj /F1 10 Tf 12 TL ( asm \(sexp\)) Tj T* ET +Q +Q +q +1 0 0 1 339.1581 75 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (145 ms) Tj T* ET +Q +Q +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 (C ) Tj /F6 10 Tf 12 TL (\256) Tj /F1 10 Tf 12 TL ( Python \(sexp\)) Tj T* ET +Q +Q +q +1 0 0 1 339.1581 57 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (154 ms) 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 ) Tj /F6 10 Tf 12 TL (\256) Tj /F1 10 Tf 12 TL ( asm \(sexp\)) Tj T* ET +Q +Q +q +1 0 0 1 339.1581 39 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (4.1 ms) Tj T* ET +Q +Q +q +1 0 0 1 6 21 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (asm ) Tj /F6 10 Tf 12 TL (\256) Tj /F1 10 Tf 12 TL ( Python \(sexp\)) Tj T* ET +Q +Q +q +1 0 0 1 339.1581 21 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (167 ms) Tj T* ET +Q +Q +q +1 0 0 1 6 3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (asm ) Tj /F6 10 Tf 12 TL (\256) Tj /F1 10 Tf 12 TL ( C \(sexp\)) Tj T* ET +Q +Q +q +1 0 0 1 339.1581 3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (4.6 ms) Tj T* ET +Q +Q +q +1 J +1 j +0 0 0 RG +.25 w +n 0 180 m 481.2283 180 l S +n 0 162 m 481.2283 162 l S +n 0 144 m 481.2283 144 l S +n 0 126 m 481.2283 126 l S +n 0 108 m 481.2283 108 l S +n 0 90 m 481.2283 90 l S +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 333.1581 0 m 333.1581 198 l S +n 0 198 m 481.2283 198 l S +n 0 0 m 481.2283 0 l S +n 0 0 m 0 198 l S +n 481.2283 0 m 481.2283 198 l S +Q +Q +Q +q +1 0 0 1 57.02362 241.0236 cm +Q +q +1 0 0 1 57.02362 199.0236 cm +q +BT 1 0 0 1 0 26 Tm .698334 Tw 12 TL /F1 10 Tf 0 0 0 rg (The asm) Tj /F6 10 Tf 12 TL (\256) Tj /F1 10 Tf 12 TL (asm cross-process is ~160\327 faster than Python) Tj /F6 10 Tf 12 TL (\256) Tj /F1 10 Tf 12 TL (Python. The binary & S-expression portals are) Tj T* 0 Tw .812256 Tw (within 10% of each other on this workload \227 the bottleneck is process startup, not serialization. For larger) Tj T* 0 Tw (heaps the binary format pulls further ahead; for portability, S-expression always wins.) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 173.0236 cm +q +BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (7.6 Mismatch Cases: Graceful Degradation) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 155.0236 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (A usable persistence layer fails well. What happens when the consumer meets unexpected input?) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 149.0236 cm +Q +q +1 0 0 1 57.02362 83.02362 cm +q +1 1 1 rg +n 0 66 481.2283 -18 re f* +.878431 .878431 .878431 rg +n 0 48 481.2283 -18 re f* +1 1 1 rg +n 0 30 481.2283 -30 re f* +0 0 0 rg +BT /F3 10 Tf 12 TL ET +q +1 0 0 1 6 51 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 96.07173 0 Td (Input) Tj T* -96.07173 0 Td ET +Q +Q +q +1 0 0 1 234.5835 51 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 19.16248 0 Td (Python) Tj T* -19.16248 0 Td ET +Q +Q +q +1 0 0 1 318.7984 51 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 32.49748 0 Td (C) Tj T* -32.49748 0 Td ET +Q +Q +q +1 0 0 1 403.0134 51 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 26.10248 0 Td (asm) Tj T* -26.10248 0 Td ET +Q +Q +0 0 0 rg +BT /F1 10 Tf 12 TL ET +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 (Empty file) Tj T* ET +Q +Q +q +1 0 0 1 234.5835 33 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (continue) Tj T* ET +Q +Q +q +1 0 0 1 318.7984 33 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (continue) Tj T* ET +Q +Q +q +1 0 0 1 403.0134 33 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (continue) Tj T* ET +Q +Q +q +1 0 0 1 6 15 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Missing file) Tj T* ET +Q +Q +q +1 0 0 1 234.5835 3 cm +q +BT 1 0 0 1 0 14 Tm 12 TL /F5 10 Tf 0 0 0 rg (file) Tj ( ) Tj (not) Tj T* (found:) Tj ( ) Tj (\205) Tj T* ET +Q +Q +q +1 0 0 1 318.7984 15 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F5 10 Tf 12 TL (error: \205) Tj T* ET +Q +Q +q +1 0 0 1 403.0134 15 cm +q +BT 1 0 0 1 0 2 Tm 12 TL /F5 10 Tf 0 0 0 rg (#f) Tj /F1 10 Tf ( + continue) Tj T* ET +Q +Q +q +1 J +1 j +0 0 0 RG +.25 w +n 0 0 m 481.2283 0 l S +n 0 48 m 481.2283 48 l S +n 0 30 m 481.2283 30 l S +n 228.5835 0 m 228.5835 66 l S +n 312.7984 0 m 312.7984 66 l S +n 397.0134 0 m 397.0134 66 l S +n 0 66 m 481.2283 66 l S +n 0 0 m 0 66 l S +n 481.2283 0 m 481.2283 66 l S +Q +Q +Q + +endstream +endobj +99 0 obj +<< +/Length 7067 +>> +stream +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +q +1 0 0 1 57.02362 681.0236 cm +q +1 1 1 rg +n 0 84 481.2283 -30 re f* +.878431 .878431 .878431 rg +n 0 54 481.2283 -18 re f* +1 1 1 rg +n 0 36 481.2283 -18 re f* +.878431 .878431 .878431 rg +n 0 18 481.2283 -18 re f* +0 0 0 rg +BT /F1 10 Tf 12 TL ET +q +1 0 0 1 6 69 cm +q +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Truncated sexp \() Tj /F5 10 Tf (\(define) Tj ( ) Tj (x) Tj /F1 10 Tf (\)) Tj T* ET +Q +Q +q +1 0 0 1 234.5835 57 cm +q +0 0 0 rg +BT 1 0 0 1 0 14 Tm /F5 10 Tf 12 TL (error:) Tj T* (unclosed) Tj T* ET +Q +Q +q +1 0 0 1 318.7984 57 cm +q +0 0 0 rg +BT 1 0 0 1 0 14 Tm /F5 10 Tf 12 TL (error:) Tj T* (unclosed) Tj T* ET +Q +Q +q +1 0 0 1 403.0134 57 cm +q +0 0 0 rg +BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL (continue) Tj T* (\(benign\)) Tj T* ET +Q +Q +q +1 0 0 1 6 39 cm +q +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Binary portal fed to ) Tj /F5 10 Tf (\(load\)) Tj T* ET +Q +Q +q +1 0 0 1 234.5835 39 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (text-file error) Tj T* ET +Q +Q +q +1 0 0 1 318.7984 39 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (reader error) Tj T* ET +Q +Q +q +1 0 0 1 403.0134 39 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (symbol errors) Tj T* ET +Q +Q +q +1 0 0 1 6 21 cm +q +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (sexp file fed to ) Tj /F5 10 Tf (portal-resume) Tj T* ET +Q +Q +q +1 0 0 1 234.5835 21 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 318.7984 21 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 403.0134 21 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F5 10 Tf 12 TL (#f) Tj T* ET +Q +Q +q +1 0 0 1 6 3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Truncated binary portal) Tj T* ET +Q +Q +q +1 0 0 1 234.5835 3 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 318.7984 3 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 403.0134 3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F5 10 Tf 12 TL (#f) Tj T* ET +Q +Q +q +1 J +1 j +0 0 0 RG +.25 w +n 0 84 m 481.2283 84 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 228.5835 0 m 228.5835 84 l S +n 312.7984 0 m 312.7984 84 l S +n 397.0134 0 m 397.0134 84 l S +n 0 0 m 0 84 l S +n 481.2283 0 m 481.2283 84 l S +n 0 0 m 481.2283 0 l S +Q +Q +Q +q +1 0 0 1 57.02362 681.0236 cm +Q +q +1 0 0 1 57.02362 615.0236 cm +q +BT 1 0 0 1 0 50 Tm 1.476556 Tw 12 TL /F1 10 Tf 0 0 0 rg (All defects surfaced & fixed during benchmark development: an asm segfault on ) Tj /F5 10 Tf (\(define) Tj ( ) Tj (x\)) Tj /F1 10 Tf ( without a) Tj T* 0 Tw 1.838453 Tw (value \(now binds to ) Tj /F5 10 Tf (VOID) Tj /F1 10 Tf (\), an asm portal-resume that accepted short headers \(now verifies ) Tj /F5 10 Tf (sys_read) Tj /F1 10 Tf T* 0 Tw 1.204272 Tw (returned a full 48 bytes & sanity-checks heap metadata\), a Python ) Tj /F5 10 Tf (file) Tj ( ) Tj (not) Tj ( ) Tj (found) Tj /F1 10 Tf ( error reporting the) Tj T* 0 Tw 1.304862 Tw (outer script path instead of the inner missing file \(now uses ) Tj /F5 10 Tf (FileNotFoundError.filename) Tj /F1 10 Tf (\). Graceful) Tj T* 0 Tw (degradation is not free; it is tested.) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 589.0236 cm +q +BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (7.7 Use Case: Distributed Primality Testing) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 462.2236 cm q q 1 0 0 1 0 0 cm @@ -3225,38 +4482,38 @@ Q Q Q q -1 0 0 1 57.02362 582.2236 cm +1 0 0 1 57.02362 418.2236 cm q -BT 1 0 0 1 0 26 Tm 1.105522 Tw 12 TL /F1 10 Tf 0 0 0 rg (Machine A starts the computation. Every 10,000 iterations, it writes a checkpoint. Machine B picks up the) Tj T* 0 Tw 2.790642 Tw /F5 10 Tf (.portal) Tj /F1 10 Tf ( file & continues from the last checkpoint. The computation migrates without either machine) Tj T* 0 Tw (needing to know about the other. Feedback \(the continuation\) carries the entire execution context.) Tj T* ET +BT 1 0 0 1 0 26 Tm 1.105522 Tw 12 TL /F1 10 Tf 0 0 0 rg (Machine A starts the computation. Every 10,000 iterations, it writes a checkpoint. Machine B picks up the) Tj T* 0 Tw 2.790642 Tw /F5 10 Tf (.portal) Tj /F1 10 Tf ( file & continues from the last checkpoint. The computation migrates without either machine) Tj T* 0 Tw (needing to know about the other. Feedback \227 the continuation \227 carries the entire execution context.) Tj T* ET Q Q q -1 0 0 1 57.02362 551.0236 cm +1 0 0 1 57.02362 387.0236 cm q BT 1 0 0 1 0 2.2 Tm 13.2 TL /F2 11 Tf .133333 .133333 .133333 rg (8. The EML Universality Proof) Tj T* ET Q Q q -1 0 0 1 57.02362 519.0236 cm +1 0 0 1 57.02362 355.0236 cm q BT 1 0 0 1 0 14 Tm 1.489873 Tw 12 TL /F1 10 Tf 0 0 0 rg (uncommonlisp ships with a mathematical proof that a single operator generates all elementary functions:) Tj T* 0 Tw /F5 10 Tf (eml\(x,) Tj ( ) Tj (y\)) Tj ( ) Tj (=) Tj ( ) Tj (exp\(x\)) Tj ( ) Tj (-) Tj ( ) Tj (ln\(y\)) Tj /F1 10 Tf (.) Tj T* ET Q Q q -1 0 0 1 57.02362 501.0236 cm +1 0 0 1 57.02362 337.0236 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Reference: "All elementary functions from a single operator" \(arXiv:2603.21852v2\).) Tj T* ET Q Q q -1 0 0 1 57.02362 475.0236 cm +1 0 0 1 57.02362 311.0236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (8.1 The Operator) Tj T* ET Q Q q -1 0 0 1 57.02362 444.2236 cm +1 0 0 1 57.02362 280.2236 cm q q 1 0 0 1 0 0 cm @@ -3277,19 +4534,19 @@ Q Q Q q -1 0 0 1 57.02362 424.2236 cm +1 0 0 1 57.02362 260.2236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (With this operator & the constant ) Tj /F5 10 Tf (1) Tj /F1 10 Tf (, the following derivation chain constructs every elementary function:) Tj T* ET Q Q q -1 0 0 1 57.02362 398.2236 cm +1 0 0 1 57.02362 234.2236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (8.2 Stage 1: Core Functions \(Depth 1--3\)) Tj T* ET Q Q q -1 0 0 1 57.02362 348.2236 cm +1 0 0 1 57.02362 184.2236 cm q q 1 0 0 1 0 0 cm @@ -3310,19 +4567,28 @@ Q Q Q q -1 0 0 1 57.02362 304.2236 cm +1 0 0 1 57.02362 140.2236 cm q BT 1 0 0 1 0 26 Tm 16.01403 Tw 12 TL /F3 10 Tf 0 0 0 rg (Proof of ln recovery) Tj /F1 10 Tf (: Let ) Tj /F5 10 Tf (a) Tj ( ) Tj (=) Tj ( ) Tj (eml\(1,x\)) Tj ( ) Tj (=) Tj ( ) Tj (e) Tj ( ) Tj (-) Tj ( ) Tj (ln\(x\)) Tj /F1 10 Tf (. Then) Tj T* 0 Tw 28.85979 Tw /F5 10 Tf (eml\(a,) Tj ( ) Tj (1\)) Tj ( ) Tj (=) Tj ( ) Tj (exp\(e) Tj ( ) Tj (-) Tj ( ) Tj (ln\(x\)\)) Tj ( ) Tj (=) Tj ( ) Tj (exp\(e\)/x) Tj /F1 10 Tf (. Then) Tj T* 0 Tw /F5 10 Tf (eml\(1,) Tj ( ) Tj (exp\(e\)/x\)) Tj ( ) Tj (=) Tj ( ) Tj (e) Tj ( ) Tj (-) Tj ( ) Tj (ln\(exp\(e\)/x\)) Tj ( ) Tj (=) Tj ( ) Tj (e) Tj ( ) Tj (-) Tj ( ) Tj (e) Tj ( ) Tj (+) Tj ( ) Tj (ln\(x\)) Tj ( ) Tj (=) Tj ( ) Tj (ln\(x\)) Tj /F1 10 Tf (.) Tj T* ET Q Q + +endstream +endobj +100 0 obj +<< +/Length 9337 +>> +stream +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 57.02362 278.2236 cm +1 0 0 1 57.02362 753.0236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (8.3 Stage 2: Arithmetic) Tj T* ET Q Q q -1 0 0 1 57.02362 189.8236 cm +1 0 0 1 57.02362 664.6236 cm q q 1 0 0 1 0 0 cm @@ -3342,13 +4608,13 @@ Q Q Q q -1 0 0 1 57.02362 163.8236 cm +1 0 0 1 57.02362 638.6236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (8.4 Stage 3: Complex Plane Access) Tj T* ET Q Q q -1 0 0 1 57.02362 113.8236 cm +1 0 0 1 57.02362 588.6236 cm q q 1 0 0 1 0 0 cm @@ -3369,28 +4635,19 @@ Q Q Q q -1 0 0 1 57.02362 81.82362 cm +1 0 0 1 57.02362 556.6236 cm q BT 1 0 0 1 0 14 Tm .253071 Tw 12 TL /F1 10 Tf 0 0 0 rg (The key insight: ) Tj /F5 10 Tf (ln) Tj /F1 10 Tf ( of a negative number enters the complex plane. Since we can construct ) Tj /F5 10 Tf (-1) Tj /F1 10 Tf ( from eml via) Tj T* 0 Tw (the subtraction chain, ) Tj /F5 10 Tf (ln\(-1\)) Tj /F1 10 Tf ( yields ) Tj /F5 10 Tf (i) Tj /F6 10 Tf 12 TL (p) Tj /F5 10 Tf 12 TL /F1 10 Tf (, from which ) Tj /F5 10 Tf /F6 10 Tf 12 TL (p) Tj /F5 10 Tf 12 TL /F1 10 Tf ( & ) Tj /F5 10 Tf (i) Tj /F1 10 Tf ( follow.) Tj T* ET Q Q - -endstream -endobj -89 0 obj -<< -/Length 10228 ->> -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 530.6236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (8.5 Stage 4: Trigonometry via Euler) Tj T* ET Q Q q -1 0 0 1 57.02362 703.0236 cm +1 0 0 1 57.02362 480.6236 cm q q 1 0 0 1 0 0 cm @@ -3411,29 +4668,29 @@ Q Q Q q -1 0 0 1 57.02362 683.0236 cm +1 0 0 1 57.02362 460.6236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (All trigonometric functions follow from complex exponentials, which follow from ) Tj /F5 10 Tf (exp) Tj /F1 10 Tf (, which follows from ) Tj /F5 10 Tf (eml) Tj /F1 10 Tf (.) Tj T* ET Q Q q -1 0 0 1 57.02362 657.0236 cm +1 0 0 1 57.02362 434.6236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (8.6 Verification & Friction Analysis) Tj T* ET Q Q q -1 0 0 1 57.02362 639.0236 cm +1 0 0 1 57.02362 416.6236 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The proof is verified at three levels, with dramatically different friction:) Tj T* ET Q Q q -1 0 0 1 57.02362 633.0236 cm +1 0 0 1 57.02362 410.6236 cm Q q -1 0 0 1 57.02362 561.0236 cm +1 0 0 1 57.02362 338.6236 cm q 1 1 1 rg n 0 72 481.2283 -18 re f* @@ -3577,34 +4834,34 @@ Q Q Q q -1 0 0 1 57.02362 561.0236 cm +1 0 0 1 57.02362 338.6236 cm Q q -1 0 0 1 57.02362 519.0236 cm +1 0 0 1 57.02362 296.6236 cm q BT 1 0 0 1 0 26 Tm .395596 Tw 12 TL /F3 10 Tf 0 0 0 rg (The formal proof is 40x faster than the brute-force search & provides mathematical certainty instead) Tj T* 0 Tw 1.066027 Tw (of floating-point tolerance.) Tj /F1 10 Tf ( This is MOAD-0001 \(the sedimentary defect\) at the proof methodology layer:) Tj T* 0 Tw (O\(N\262\) search friction where O\(1\) algebraic reasoning suffices.) Tj T* ET Q Q q -1 0 0 1 57.02362 465.0236 cm +1 0 0 1 57.02362 242.6236 cm q BT 1 0 0 1 0 38 Tm 2.309862 Tw 12 TL /F1 10 Tf 0 0 0 rg (The numerical approaches enumerate all pairwise EML compositions at each depth, comparing results) Tj T* 0 Tw .653022 Tw (against target functions. This grows quadratically with the number of known values. The Lean proof does 5) Tj T* 0 Tw .327397 Tw (algebraic rewrites, each applying an axiom \() Tj /F5 10 Tf (exp\(ln\(x\)\)) Tj ( ) Tj (=) Tj ( ) Tj (x) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (ln\(exp\(x\)\)) Tj ( ) Tj (=) Tj ( ) Tj (x) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (ln\(1\)) Tj ( ) Tj (=) Tj ( ) Tj (0) Tj /F1 10 Tf (\). The type) Tj T* 0 Tw (checker confirms each rewrite in microseconds. No search. No tolerance. No conjecture dependency.) Tj T* ET Q Q q -1 0 0 1 57.02362 411.0236 cm +1 0 0 1 57.02362 188.6236 cm q BT 1 0 0 1 0 38 Tm 3.571147 Tw 12 TL /F3 10 Tf 0 0 0 rg (Lesson) Tj /F1 10 Tf (: The fastest path to truth is not computation \227 it is understanding. When you know ) Tj /F4 10 Tf (why) Tj /F1 10 Tf T* 0 Tw .96189 Tw /F5 10 Tf (eml\(1,) Tj ( ) Tj (eml\(eml\(1,x\),) Tj ( ) Tj (1\)\)) Tj ( ) Tj (=) Tj ( ) Tj (ln\(x\)) Tj /F1 10 Tf (, you verify it in microseconds. When you don't, you search for) Tj T* 0 Tw 1.513223 Tw (hours. Proof assistants eliminate the quadratic friction of verification. They are the hash set to numerical) Tj T* 0 Tw (analysis's nested loop.) Tj T* ET Q Q q -1 0 0 1 57.02362 405.0236 cm +1 0 0 1 57.02362 182.6236 cm Q q -1 0 0 1 57.02362 405.0236 cm +1 0 0 1 57.02362 182.6236 cm Q q -1 0 0 1 57.02362 369.0236 cm +1 0 0 1 57.02362 146.6236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -3626,10 +4883,10 @@ Q Q Q q -1 0 0 1 57.02362 363.0236 cm +1 0 0 1 57.02362 140.6236 cm Q q -1 0 0 1 57.02362 327.0236 cm +1 0 0 1 57.02362 104.6236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -3651,10 +4908,10 @@ Q Q Q q -1 0 0 1 57.02362 321.0236 cm +1 0 0 1 57.02362 98.62362 cm Q q -1 0 0 1 57.02362 297.0236 cm +1 0 0 1 57.02362 74.62362 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -3676,10 +4933,19 @@ Q Q Q q -1 0 0 1 57.02362 297.0236 cm +1 0 0 1 57.02362 74.62362 cm Q + +endstream +endobj +101 0 obj +<< +/Length 8656 +>> +stream +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 57.02362 227.8236 cm +1 0 0 1 57.02362 703.8236 cm q q 1 0 0 1 0 0 cm @@ -3700,81 +4966,72 @@ Q Q Q q -1 0 0 1 57.02362 183.8236 cm +1 0 0 1 57.02362 659.8236 cm q BT 1 0 0 1 0 26 Tm 4.138556 Tw 12 TL /F1 10 Tf 0 0 0 rg (The Lean proof operates over abstract ) Tj /F5 10 Tf (exp) Tj /F1 10 Tf ( & ) Tj /F5 10 Tf (ln) Tj /F1 10 Tf ( functions with the axioms ) Tj /F5 10 Tf (exp\(ln\(x\)\)) Tj ( ) Tj (=) Tj ( ) Tj (x) Tj /F1 10 Tf (,) Tj T* 0 Tw 2.484897 Tw /F5 10 Tf (ln\(exp\(x\)\)) Tj ( ) Tj (=) Tj ( ) Tj (x) Tj /F1 10 Tf (, & ) Tj /F5 10 Tf (ln\(1\)) Tj ( ) Tj (=) Tj ( ) Tj (0) Tj /F1 10 Tf (. This makes the result independent of any particular real number) Tj T* 0 Tw (implementation.) Tj T* ET Q Q q -1 0 0 1 57.02362 152.6236 cm +1 0 0 1 57.02362 628.6236 cm q BT 1 0 0 1 0 2.2 Tm 13.2 TL /F2 11 Tf .133333 .133333 .133333 rg (9. Language Coverage) Tj T* ET Q Q q -1 0 0 1 57.02362 132.6236 cm +1 0 0 1 57.02362 608.6236 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (uncommonlisp implements a near-complete R7RS-small Scheme:) Tj T* ET Q Q q -1 0 0 1 57.02362 78.62362 cm +1 0 0 1 57.02362 554.6236 cm q BT 1 0 0 1 0 38 Tm 1.369223 Tw 12 TL /F3 10 Tf 0 0 0 rg (Special forms) Tj /F1 10 Tf ( \(32\): ) 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 /F6 10 Tf 12 TL (l) Tj /F5 10 Tf 12 TL /F1 10 Tf (, ) Tj /F5 10 Tf (if) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (cond) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (case) 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 (begin) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (let) Tj /F1 10 Tf (,) Tj T* 0 Tw 10.15262 Tw /F5 10 Tf (let*) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (letrec) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (letrec*) Tj /F1 10 Tf (, named-let, ) Tj /F5 10 Tf (do) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (quasiquote) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (define-macro) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (define-syntax) Tj /F1 10 Tf (,) Tj T* 0 Tw 3.646907 Tw /F5 10 Tf (syntax-rules) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (let-syntax) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (letrec-syntax) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (apply) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (eval) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (values) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (call/cc) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (dynamic-wind) Tj /F1 10 Tf (,) Tj T* 0 Tw /F5 10 Tf (guard) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (parameterize) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (load) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (error) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (module) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (import) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (define-record-type) Tj /F1 10 Tf (.) Tj T* ET Q Q - -endstream -endobj -90 0 obj -<< -/Length 12171 ->> -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 +1 0 0 1 57.02362 524.6236 cm q BT 1 0 0 1 0 14 Tm .150642 Tw 12 TL /F3 10 Tf 0 0 0 rg (Built-in functions) Tj /F1 10 Tf ( \(100+\): Full arithmetic \(exact rationals, inexact reals, trigonometry\), pairs & lists \(SRFI-1\),) Tj T* 0 Tw (strings \(mutable\), characters, vectors, hash tables, I/O \(ports, file system\), system interface, Python interop.) Tj T* ET Q Q q -1 0 0 1 57.02362 711.0236 cm +1 0 0 1 57.02362 494.6236 cm q BT 1 0 0 1 0 14 Tm 2.274835 Tw 12 TL /F3 10 Tf 0 0 0 rg (Hygienic macros) Tj /F1 10 Tf (: ) Tj /F5 10 Tf (syntax-rules) Tj /F1 10 Tf ( with ellipsis \() Tj /F5 10 Tf (...) Tj /F1 10 Tf (\) support. Pattern matching, template instantiation,) Tj T* 0 Tw (proper hygiene. Also ) Tj /F5 10 Tf (define-macro) Tj /F1 10 Tf ( for procedural macros.) Tj T* ET Q Q q -1 0 0 1 57.02362 681.0236 cm +1 0 0 1 57.02362 464.6236 cm q BT 1 0 0 1 0 14 Tm 1.958835 Tw 12 TL /F3 10 Tf 0 0 0 rg (Standard library) Tj /F1 10 Tf ( \() Tj /F5 10 Tf (stdlib.lsp) Tj /F1 10 Tf (, 385 lines\): Additional macros \() Tj /F5 10 Tf (swap!) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (fluid-let) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (while) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (dotimes) Tj /F1 10 Tf (\),) Tj T* 0 Tw (utility functions, simple object system, SRFI-2/8/64 test framework.) Tj T* ET Q Q q -1 0 0 1 57.02362 639.0236 cm +1 0 0 1 57.02362 410.6236 cm q -BT 1 0 0 1 0 26 Tm 2.004488 Tw 12 TL /F3 10 Tf 0 0 0 rg (Test suite) Tj /F1 10 Tf (: 529 tests covering lexing, parsing, special forms, bytecode compilation, macros \(hygienic &) Tj T* 0 Tw 3.388705 Tw (procedural\), continuations, generators, record types, modules, arithmetic, higher-order functions, error) Tj T* 0 Tw (handling, & portal serialization.) Tj T* ET +BT 1 0 0 1 0 38 Tm 1.569862 Tw 12 TL /F3 10 Tf 0 0 0 rg (Test suite) Tj /F1 10 Tf (: 974 verified assertions covering lexing, parsing, special forms, bytecode compilation, macros) Tj T* 0 Tw .214835 Tw (\(hygienic & procedural\), continuations, generators, record types, modules, arithmetic, higher-order functions,) Tj T* 0 Tw 4.238031 Tw (error handling, portal serialization, cross-implementation portal exchange, file I/O parity, & graceful) Tj T* 0 Tw (degradation on mismatched or corrupt input.) Tj T* ET Q Q q -1 0 0 1 57.02362 607.8236 cm +1 0 0 1 57.02362 379.4236 cm q BT 1 0 0 1 0 2.2 Tm 13.2 TL /F2 11 Tf .133333 .133333 .133333 rg (10. Relationship to Companion Papers) Tj T* ET Q Q q -1 0 0 1 57.02362 587.8236 cm +1 0 0 1 57.02362 359.4236 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (uncommonlisp forms one piece of a larger permacomputer machine learning stack:) Tj T* ET Q Q q -1 0 0 1 57.02362 581.8236 cm +1 0 0 1 57.02362 353.4236 cm Q q -1 0 0 1 57.02362 443.8236 cm +1 0 0 1 57.02362 215.4236 cm q 1 1 1 rg n 0 138 481.2283 -18 re f* @@ -3911,25 +5168,25 @@ Q Q Q q -1 0 0 1 57.02362 443.8236 cm +1 0 0 1 57.02362 215.4236 cm Q q -1 0 0 1 57.02362 389.8236 cm +1 0 0 1 57.02362 161.4236 cm q BT 1 0 0 1 0 38 Tm 2.814488 Tw 12 TL /F1 10 Tf 0 0 0 rg (uncommonlisp provides the runtime layer: a language that can checkpoint its own execution, migrate) Tj T* 0 Tw 2.355696 Tw (between machines, & resume from serialized state. The portal system enables distributed computation) Tj T* 0 Tw 1.588941 Tw (across permacomputer nodes. Categorization & feedback activities could run inside uncommonlisp's VM,) Tj T* 0 Tw (with ) Tj /F5 10 Tf (call/cc) Tj /F1 10 Tf ( providing the state machine transitions & portal providing persistence.) Tj T* ET Q Q q -1 0 0 1 57.02362 358.6236 cm +1 0 0 1 57.02362 130.2236 cm q -BT 1 0 0 1 0 2.2 Tm 13.2 TL /F2 11 Tf .133333 .133333 .133333 rg (11. Four 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. Three Implementations, One Language) Tj T* ET Q Q q -1 0 0 1 57.02362 344.6236 cm +1 0 0 1 57.02362 116.2236 cm Q q -1 0 0 1 57.02362 332.6236 cm +1 0 0 1 57.02362 104.2236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -3945,276 +5202,285 @@ Q Q Q q -1 0 0 1 57.02362 332.6236 cm +1 0 0 1 57.02362 104.2236 cm Q + +endstream +endobj +102 0 obj +<< +/Length 13413 +>> +stream +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 57.02362 290.6236 cm +1 0 0 1 57.02362 729.0236 cm q 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 284.6236 cm +1 0 0 1 57.02362 723.0236 cm Q q -1 0 0 1 57.02362 152.6236 cm +1 0 0 1 57.02362 603.0236 cm q 1 1 1 rg -n 0 132 481.2283 -30 re f* +n 0 120 481.2283 -30 re f* .878431 .878431 .878431 rg -n 0 102 481.2283 -18 re f* +n 0 90 481.2283 -18 re f* 1 1 1 rg -n 0 84 481.2283 -18 re f* +n 0 72 481.2283 -18 re f* .878431 .878431 .878431 rg -n 0 66 481.2283 -18 re f* +n 0 54 481.2283 -18 re f* 1 1 1 rg -n 0 48 481.2283 -30 re f* +n 0 36 481.2283 -18 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 105 cm +1 0 0 1 6 93 cm q 0 0 0 rg -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 +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 27.47366 0 Td (Implementation) Tj T* -27.47366 0 Td ET Q Q q -1 0 0 1 147.5377 105 cm +1 0 0 1 146.8473 93 cm q 0 0 0 rg -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 +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 4.414553 0 Td (Lines) Tj T* -4.414553 0 Td ET Q Q q -1 0 0 1 204.1528 105 cm +1 0 0 1 193.7964 93 cm q 0 0 0 rg -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 +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 4.723192 0 Td (ack\(3,4\)) Tj T* -4.723192 0 Td ET Q Q q -1 0 0 1 260.7679 105 cm +1 0 0 1 252.4828 93 cm q 0 0 0 rg -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 +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 8.343192 0 Td (fib\(35\)) Tj T* -8.343192 0 Td ET Q Q q -1 0 0 1 317.383 105 cm +1 0 0 1 311.1692 93 cm q 0 0 0 rg -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 +BT 1 0 0 1 0 14 Tm /F3 10 Tf 12 TL 2.387511 0 Td (sum-to\(50) Tj T* 19.445 0 Td (k\)) Tj T* -21.83251 0 Td ET Q Q q -1 0 0 1 373.9981 105 cm +1 0 0 1 375.7242 93 cm q 0 0 0 rg -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 +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 7.783192 0 Td (Binary) Tj T* -7.783192 0 Td ET Q Q q -1 0 0 1 430.6132 105 cm +1 0 0 1 434.4106 93 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 +BT 1 0 0 1 0 14 Tm /F3 10 Tf 12 TL 2.073873 0 Td (Depend) Tj T* 2.77 0 Td (encies) Tj T* -4.843873 0 Td ET Q Q 0 0 0 rg BT /F1 10 Tf 12 TL ET q -1 0 0 1 6 87 cm +1 0 0 1 6 75 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 147.5377 87 cm +1 0 0 1 146.8473 75 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (10,000) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (~9k) Tj T* ET Q Q q -1 0 0 1 204.1528 87 cm +1 0 0 1 193.7964 75 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.19ms) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.19 ms) Tj T* ET Q Q q -1 0 0 1 260.7679 87 cm +1 0 0 1 252.4828 75 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.09ms) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.09 ms) Tj T* ET Q Q q -1 0 0 1 317.383 87 cm +1 0 0 1 311.1692 75 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.55ms) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.55 ms) Tj T* ET Q Q q -1 0 0 1 373.9981 87 cm +1 0 0 1 375.7242 75 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (171KB) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (205 KB) Tj T* ET Q Q q -1 0 0 1 430.6132 87 cm +1 0 0 1 434.4106 75 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 +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 (CPython \(reference\)) Tj T* ET Q Q q -1 0 0 1 147.5377 69 cm +1 0 0 1 146.8473 57 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 +1 0 0 1 193.7964 57 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (1.3ms) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (1.3 ms) Tj T* ET Q Q q -1 0 0 1 260.7679 69 cm +1 0 0 1 252.4828 57 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.006ms) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.006 ms) Tj T* ET Q Q q -1 0 0 1 317.383 69 cm +1 0 0 1 311.1692 57 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (5.5ms) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (5.5 ms) Tj T* ET Q Q q -1 0 0 1 373.9981 69 cm +1 0 0 1 375.7242 57 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 +1 0 0 1 434.4106 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 51 cm +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 interpreter) Tj T* ET Q Q q -1 0 0 1 147.5377 51 cm +1 0 0 1 146.8473 39 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (10,000) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (~9k) Tj T* ET Q Q q -1 0 0 1 204.1528 51 cm +1 0 0 1 193.7964 39 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (20ms) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (20 ms) Tj T* ET Q Q q -1 0 0 1 260.7679 51 cm +1 0 0 1 252.4828 39 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.06ms) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.06 ms) Tj T* ET Q Q q -1 0 0 1 317.383 51 cm +1 0 0 1 311.1692 39 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (109ms) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (109 ms) Tj T* ET Q Q q -1 0 0 1 373.9981 51 cm +1 0 0 1 375.7242 39 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (171KB) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (205 KB) Tj T* ET Q Q q -1 0 0 1 430.6132 51 cm +1 0 0 1 434.4106 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 33 cm +1 0 0 1 6 21 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 +1 0 0 1 146.8473 21 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (3,324) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (3,678) Tj T* ET Q Q q -1 0 0 1 204.1528 33 cm +1 0 0 1 193.7964 21 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (149ms) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (149 ms) Tj T* ET Q Q q -1 0 0 1 260.7679 33 cm +1 0 0 1 252.4828 21 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.75ms) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.75 ms) Tj T* ET Q Q q -1 0 0 1 317.383 33 cm +1 0 0 1 311.1692 21 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (437ms) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (437 ms) Tj T* ET Q Q q -1 0 0 1 373.9981 21 cm +1 0 0 1 375.7242 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 +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 33 cm +1 0 0 1 434.4106 21 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Python 3) Tj T* ET @@ -4224,46 +5490,46 @@ q 1 0 0 1 6 3 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (x86_64 Assembly) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (x86_64 assembly \(\206\)) Tj T* ET Q Q q -1 0 0 1 147.5377 3 cm +1 0 0 1 146.8473 3 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (3,100) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (4,455) Tj T* ET Q Q q -1 0 0 1 204.1528 3 cm +1 0 0 1 193.7964 3 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (8ms*) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (8 ms) Tj T* ET Q Q q -1 0 0 1 260.7679 3 cm +1 0 0 1 252.4828 3 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.6ms*) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (0.6 ms) Tj T* ET Q Q q -1 0 0 1 317.383 3 cm +1 0 0 1 311.1692 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 (43 ms) Tj T* ET Q Q q -1 0 0 1 373.9981 3 cm +1 0 0 1 375.7242 3 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (13KB) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (22 KB) Tj T* ET Q Q q -1 0 0 1 430.6132 3 cm +1 0 0 1 434.4106 3 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (none) Tj T* ET @@ -4274,88 +5540,71 @@ q 1 j 0 0 0 RG .25 w -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 90 m 481.2283 90 l S +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 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 140.8473 0 m 140.8473 120 l S +n 187.7964 0 m 187.7964 120 l S +n 246.4828 0 m 246.4828 120 l S +n 305.1692 0 m 305.1692 120 l S +n 369.7242 0 m 369.7242 120 l S +n 428.4106 0 m 428.4106 120 l S +n 0 120 m 481.2283 120 l S n 0 0 m 481.2283 0 l S -n 0 0 m 0 132 l S -n 481.2283 0 m 481.2283 132 l S +n 0 0 m 0 120 l S +n 481.2283 0 m 481.2283 120 l S Q Q Q q -1 0 0 1 57.02362 152.6236 cm +1 0 0 1 57.02362 603.0236 cm Q q -1 0 0 1 57.02362 122.6236 cm +1 0 0 1 57.02362 573.0236 cm q -0 0 0 rg -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 +BT 1 0 0 1 0 14 Tm 1.743453 Tw 12 TL /F1 10 Tf 0 0 0 rg (All C & Python benchmarks measured in-process \(no startup overhead\). Assembly times \(\206\) include full) Tj T* 0 Tw (process lifetime: startup + tokenizer + parser + eval. "\227" = not applicable / interpreted.) Tj T* ET Q Q q -1 0 0 1 57.02362 68.62362 cm +1 0 0 1 57.02362 495.0236 cm q -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 - -endstream -endobj -91 0 obj -<< -/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 741.0236 cm -q -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 +BT 1 0 0 1 0 62 Tm .118138 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.19 ms \(JIT\) vs 1.3 ms) Tj T* 0 Tw .050491 Tw (\(CPython\) \227 7\327 faster. ) Tj /F5 10 Tf (sum-to\(50000\)) Tj /F1 10 Tf ( completes in 0.55 ms \(JIT\) vs 5.5 ms \(CPython\) \227 10\327 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 .786027 Tw (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 675.0236 cm +1 0 0 1 57.02362 405.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 +BT 1 0 0 1 0 74 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 ( 4,455 lines of GNU assembler,) Tj T* 0 Tw 2.416796 Tw /F3 10 Tf (22 KB stripped binary) Tj /F1 10 Tf (, zero external dependencies. Only seven Linux syscalls \() Tj /F5 10 Tf (read) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (write) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (open) Tj /F1 10 Tf (,) Tj T* 0 Tw 1.843196 Tw /F5 10 Tf (close) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (lseek) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (mmap) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (munmap) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (exit) Tj /F1 10 Tf (\). A bump allocator, tag-in-low-3-bits values, ) Tj /F3 10 Tf (79 builtins) Tj /F1 10 Tf ( \(including) Tj T* 0 Tw 1.753058 Tw /F5 10 Tf (load) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (open-output-file) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (close-port) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (port?) Tj /F1 10 Tf (, port-aware ) Tj /F5 10 Tf (display) Tj /F1 10 Tf (/) Tj /F5 10 Tf (write) Tj /F1 10 Tf (/) Tj /F5 10 Tf (newline) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (write-file) Tj /F1 10 Tf (,) Tj T* 0 Tw 3.052739 Tw /F5 10 Tf (file-) Tj (>) Tj (string) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (portal-save) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (portal-resume) Tj /F1 10 Tf (\), & 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.77989 Tw /F5 10 Tf (\(fib) Tj ( ) Tj (35\)) Tj ( ) Tj (=) Tj ( ) Tj (9227465) Tj /F1 10 Tf ( correctly \227 2.5\327 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 +1 0 0 1 57.02362 351.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 +BT 1 0 0 1 0 38 Tm 2.546213 Tw 12 TL /F3 10 Tf 0 0 0 rg (The bytecode VM delivers 7--19\327 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 +1 0 0 1 57.02362 325.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 577.0236 cm +1 0 0 1 57.02362 307.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 +BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (974 verified assertions) Tj /F1 10 Tf ( across all implementations, all green under ) 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 571.0236 cm +1 0 0 1 57.02362 301.0236 cm Q q -1 0 0 1 57.02362 571.0236 cm +1 0 0 1 57.02362 301.0236 cm Q q -1 0 0 1 57.02362 559.0236 cm +1 0 0 1 57.02362 289.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -4369,7 +5618,7 @@ 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 +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Python unit + integration: ) Tj /F3 10 Tf (571 tests) Tj /F1 10 Tf ( \() Tj /F5 10 Tf (tests.py) Tj /F1 10 Tf (\)) Tj T* ET Q Q q @@ -4377,10 +5626,10 @@ Q Q Q q -1 0 0 1 57.02362 553.0236 cm +1 0 0 1 57.02362 283.0236 cm Q q -1 0 0 1 57.02362 541.0236 cm +1 0 0 1 57.02362 271.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -4394,7 +5643,7 @@ 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 +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (C unit + integration + JIT + continuations + portal: ) Tj /F3 10 Tf (83 tests) Tj /F1 10 Tf ( \() Tj /F5 10 Tf (c/test.c) Tj /F1 10 Tf (\)) Tj T* ET Q Q q @@ -4402,10 +5651,10 @@ Q Q Q q -1 0 0 1 57.02362 535.0236 cm +1 0 0 1 57.02362 265.0236 cm Q q -1 0 0 1 57.02362 523.0236 cm +1 0 0 1 57.02362 253.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -4419,7 +5668,7 @@ 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 +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Assembly unit + integration + functional: ) Tj /F3 10 Tf (131 tests) Tj /F1 10 Tf ( \() Tj /F5 10 Tf (asm/test.sh) Tj /F1 10 Tf (\)) Tj T* ET Q Q q @@ -4427,10 +5676,10 @@ Q Q Q q -1 0 0 1 57.02362 517.0236 cm +1 0 0 1 57.02362 247.0236 cm Q q -1 0 0 1 57.02362 505.0236 cm +1 0 0 1 57.02362 235.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -4444,7 +5693,7 @@ 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 +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Shared functional \(same ) Tj /F5 10 Tf (.lsp) Tj /F1 10 Tf ( in Python + C\): ) Tj /F3 10 Tf (189 tests) Tj /F1 10 Tf ( \() Tj /F5 10 Tf (tests/functional.lsp) Tj /F1 10 Tf (\)) Tj T* ET Q Q q @@ -4452,47 +5701,498 @@ Q Q Q q -1 0 0 1 57.02362 487.0236 cm +1 0 0 1 57.02362 217.0236 cm Q q -1 0 0 1 57.02362 469.0236 cm +1 0 0 1 57.02362 175.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 +BT 1 0 0 1 0 26 Tm .98631 Tw 12 TL /F1 10 Tf 0 0 0 rg (The shared functional suite matters: it runs byte-identical Scheme source through two different runtimes &) Tj T* 0 Tw .353432 Tw (compares output. Python & C agree 189 times per run. When they disagree, that tells us something specific) Tj T* 0 Tw (& actionable.) Tj T* ET Q Q q -1 0 0 1 57.02362 437.8236 cm +1 0 0 1 57.02362 145.0236 cm +q +BT 1 0 0 1 0 14 Tm 3.001043 Tw 12 TL /F1 10 Tf 0 0 0 rg (Cross-implementation portal exchange is verified separately: ) Tj /F5 10 Tf (tests/portal-cross-test.sh) Tj /F1 10 Tf ( runs 9) Tj T* 0 Tw (producer\327consumer combinations. All 9 green.) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 119.0236 cm +q +BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (11.2 File I/O Parity) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 89.02362 cm +q +0 0 0 rg +BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .155596 Tw (All three implementations share the same minimal file I/O vocabulary \227 discovered necessary while building) Tj T* 0 Tw (the cross-impl portal:) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 83.02362 cm +Q +q +1 0 0 1 57.02362 65.02362 cm +q +1 1 1 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 3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 62.38018 0 Td (Builtin) Tj T* -62.38018 0 Td ET +Q +Q +q +1 0 0 1 173.8704 3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 24.94678 0 Td (Semantics) Tj T* -24.94678 0 Td ET +Q +Q +q +1 0 0 1 285.7839 3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 21.45907 0 Td (Py) Tj T* -21.45907 0 Td ET +Q +Q +q +1 0 0 1 352.9321 3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 23.96407 0 Td (C) Tj T* -23.96407 0 Td ET +Q +Q +q +1 0 0 1 420.0802 3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 17.56907 0 Td (asm) Tj T* -17.56907 0 Td ET +Q +Q +q +1 J +1 j +0 0 0 RG +.25 w +n 0 0 m 481.2283 0 l S +n 167.8704 0 m 167.8704 18 l S +n 279.7839 0 m 279.7839 18 l S +n 346.9321 0 m 346.9321 18 l S +n 414.0802 0 m 414.0802 18 l S +n 0 18 m 481.2283 18 l S +n 0 0 m 0 18 l S +n 481.2283 0 m 481.2283 18 l S +Q +Q +Q + +endstream +endobj +103 0 obj +<< +/Length 10868 +>> +stream +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +q +1 0 0 1 57.02362 603.0236 cm +q +1 1 1 rg +n 0 162 481.2283 -18 re f* +.878431 .878431 .878431 rg +n 0 144 481.2283 -18 re f* +1 1 1 rg +n 0 126 481.2283 -18 re f* +.878431 .878431 .878431 rg +n 0 108 481.2283 -18 re f* +1 1 1 rg +n 0 90 481.2283 -18 re f* +.878431 .878431 .878431 rg +n 0 72 481.2283 -18 re f* +1 1 1 rg +n 0 54 481.2283 -18 re f* +.878431 .878431 .878431 rg +n 0 36 481.2283 -18 re f* +1 1 1 rg +n 0 18 481.2283 -18 re f* +0 0 0 rg +BT /F1 10 Tf 12 TL ET +q +1 0 0 1 6 147 cm +q +BT 1 0 0 1 0 2 Tm 12 TL /F5 10 Tf 0 0 0 rg (\(load) Tj ( ) Tj ("path"\)) Tj T* ET +Q +Q +q +1 0 0 1 173.8704 147 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (read + eval forms) Tj T* ET +Q +Q +q +1 0 0 1 285.7839 147 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL /F7 10 Tf 12 TL (3) Tj /F1 10 Tf 12 TL T* ET +Q +Q +q +1 0 0 1 352.9321 147 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL /F7 10 Tf 12 TL (3) Tj /F1 10 Tf 12 TL T* ET +Q +Q +q +1 0 0 1 420.0802 147 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL /F7 10 Tf 12 TL (3) Tj /F1 10 Tf 12 TL T* ET +Q +Q +q +1 0 0 1 6 129 cm +q +BT 1 0 0 1 0 2 Tm 12 TL /F5 10 Tf 0 0 0 rg (\(open-output-file) Tj ( ) Tj (p\)) Tj T* ET +Q +Q +q +1 0 0 1 173.8704 129 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (open, return port) Tj T* ET +Q +Q +q +1 0 0 1 285.7839 129 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL /F7 10 Tf 12 TL (3) Tj /F1 10 Tf 12 TL T* ET +Q +Q +q +1 0 0 1 352.9321 129 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL /F7 10 Tf 12 TL (3) Tj /F1 10 Tf 12 TL T* ET +Q +Q +q +1 0 0 1 420.0802 129 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL /F7 10 Tf 12 TL (3) Tj /F1 10 Tf 12 TL T* ET +Q +Q +q +1 0 0 1 6 111 cm +q +BT 1 0 0 1 0 2 Tm 12 TL /F5 10 Tf 0 0 0 rg (\(close-port) Tj ( ) Tj (p\)) Tj T* ET +Q +Q +q +1 0 0 1 173.8704 111 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (close port) Tj T* ET +Q +Q +q +1 0 0 1 285.7839 111 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL /F7 10 Tf 12 TL (3) Tj /F1 10 Tf 12 TL T* ET +Q +Q +q +1 0 0 1 352.9321 111 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL /F7 10 Tf 12 TL (3) Tj /F1 10 Tf 12 TL T* ET +Q +Q +q +1 0 0 1 420.0802 111 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL /F7 10 Tf 12 TL (3) Tj /F1 10 Tf 12 TL T* ET +Q +Q +q +1 0 0 1 6 93 cm +q +BT 1 0 0 1 0 2 Tm 12 TL /F5 10 Tf 0 0 0 rg (\(port?) Tj ( ) Tj (x\)) Tj T* ET +Q +Q +q +1 0 0 1 173.8704 93 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (port predicate) Tj T* ET +Q +Q +q +1 0 0 1 285.7839 93 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL /F7 10 Tf 12 TL (3) Tj /F1 10 Tf 12 TL T* ET +Q +Q +q +1 0 0 1 352.9321 93 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL /F7 10 Tf 12 TL (3) Tj /F1 10 Tf 12 TL T* ET +Q +Q +q +1 0 0 1 420.0802 93 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL /F7 10 Tf 12 TL (3) Tj /F1 10 Tf 12 TL T* ET +Q +Q +q +1 0 0 1 6 75 cm +q +BT 1 0 0 1 0 2 Tm 12 TL /F5 10 Tf 0 0 0 rg (\(display) Tj ( ) Tj (v) Tj ( ) Tj ([port]\)) Tj T* ET +Q +Q +q +1 0 0 1 173.8704 75 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (to stdout or port) Tj T* ET +Q +Q +q +1 0 0 1 285.7839 75 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL /F7 10 Tf 12 TL (3) Tj /F1 10 Tf 12 TL T* ET +Q +Q +q +1 0 0 1 352.9321 75 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL /F7 10 Tf 12 TL (3) Tj /F1 10 Tf 12 TL T* ET +Q +Q +q +1 0 0 1 420.0802 75 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL /F7 10 Tf 12 TL (3) Tj /F1 10 Tf 12 TL T* ET +Q +Q +q +1 0 0 1 6 57 cm +q +BT 1 0 0 1 0 2 Tm 12 TL /F5 10 Tf 0 0 0 rg (\(write) Tj ( ) Tj (v) Tj ( ) Tj ([port]\)) Tj T* ET +Q +Q +q +1 0 0 1 173.8704 57 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (quoted / readable) Tj T* ET +Q +Q +q +1 0 0 1 285.7839 57 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL /F7 10 Tf 12 TL (3) Tj /F1 10 Tf 12 TL T* ET +Q +Q +q +1 0 0 1 352.9321 57 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL /F7 10 Tf 12 TL (3) Tj /F1 10 Tf 12 TL T* ET +Q +Q +q +1 0 0 1 420.0802 57 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL /F7 10 Tf 12 TL (3) Tj /F1 10 Tf 12 TL T* ET +Q +Q +q +1 0 0 1 6 39 cm +q +BT 1 0 0 1 0 2 Tm 12 TL /F5 10 Tf 0 0 0 rg (\(newline) Tj ( ) Tj ([port]\)) Tj T* ET +Q +Q +q +1 0 0 1 173.8704 39 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (line break) Tj T* ET +Q +Q +q +1 0 0 1 285.7839 39 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL /F7 10 Tf 12 TL (3) Tj /F1 10 Tf 12 TL T* ET +Q +Q +q +1 0 0 1 352.9321 39 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL /F7 10 Tf 12 TL (3) Tj /F1 10 Tf 12 TL T* ET +Q +Q +q +1 0 0 1 420.0802 39 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL /F7 10 Tf 12 TL (3) Tj /F1 10 Tf 12 TL T* ET +Q +Q +q +1 0 0 1 6 21 cm +q +BT 1 0 0 1 0 2 Tm 12 TL /F5 10 Tf 0 0 0 rg (\(write-file) Tj ( ) Tj (path) Tj ( ) Tj (str\)) Tj T* ET +Q +Q +q +1 0 0 1 173.8704 21 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (bytes in, #t/#f) Tj T* ET +Q +Q +q +1 0 0 1 285.7839 21 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL /F7 10 Tf 12 TL (3) Tj /F1 10 Tf 12 TL T* ET +Q +Q +q +1 0 0 1 352.9321 21 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL /F7 10 Tf 12 TL (3) Tj /F1 10 Tf 12 TL T* ET +Q +Q +q +1 0 0 1 420.0802 21 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL /F7 10 Tf 12 TL (3) Tj /F1 10 Tf 12 TL T* ET +Q +Q +q +1 0 0 1 6 3 cm +q +BT 1 0 0 1 0 2 Tm 12 TL /F5 10 Tf 0 0 0 rg (\(file-) Tj (>) Tj (string) Tj ( ) Tj (path\)) Tj T* ET +Q +Q +q +1 0 0 1 173.8704 3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (read whole file) Tj T* ET +Q +Q +q +1 0 0 1 285.7839 3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL /F7 10 Tf 12 TL (3) Tj /F1 10 Tf 12 TL T* ET +Q +Q +q +1 0 0 1 352.9321 3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL /F7 10 Tf 12 TL (3) Tj /F1 10 Tf 12 TL T* ET +Q +Q +q +1 0 0 1 420.0802 3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL /F7 10 Tf 12 TL (3) Tj /F1 10 Tf 12 TL T* ET +Q +Q +q +1 J +1 j +0 0 0 RG +.25 w +n 0 162 m 481.2283 162 l S +n 0 144 m 481.2283 144 l S +n 0 126 m 481.2283 126 l S +n 0 108 m 481.2283 108 l S +n 0 90 m 481.2283 90 l S +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 167.8704 0 m 167.8704 162 l S +n 279.7839 0 m 279.7839 162 l S +n 346.9321 0 m 346.9321 162 l S +n 414.0802 0 m 414.0802 162 l S +n 0 0 m 0 162 l S +n 481.2283 0 m 481.2283 162 l S +n 0 0 m 481.2283 0 l S +Q +Q +Q +q +1 0 0 1 57.02362 603.0236 cm +Q +q +1 0 0 1 57.02362 537.0236 cm +q +BT 1 0 0 1 0 50 Tm .254609 Tw 12 TL /F1 10 Tf 0 0 0 rg (The asm port representation deserves a note. Because all three tag bits are consumed by the existing value) Tj T* 0 Tw 4.102038 Tw (types \(int/pair/sym/closure/builtin/special/string/vector\), we encode ports as ) Tj /F5 10 Tf (SPECIAL) Tj /F1 10 Tf ( values ) Tj /F6 10 Tf 12 TL (\263) Tj /F1 10 Tf 12 TL ( 1000:) Tj T* 0 Tw 8.520835 Tw /F5 10 Tf (port_val) Tj ( ) Tj (=) Tj ( ) Tj (\(\(PORT_SPECIAL_BASE) Tj ( ) Tj (+) Tj ( ) Tj (fd\)) Tj ( ) Tj (<) Tj (<) Tj ( ) Tj (3\)) Tj ( ) Tj (|) Tj ( ) Tj (TAG_SPECIAL) Tj /F1 10 Tf (. Extraction is) Tj T* 0 Tw .162256 Tw /F5 10 Tf (fd) Tj ( ) Tj (=) Tj ( ) Tj (\(val) Tj ( ) Tj (>) Tj (>) Tj ( ) Tj (3\)) Tj ( ) Tj (-) Tj ( ) Tj (PORT_SPECIAL_BASE) Tj /F1 10 Tf (. ) Tj /F5 10 Tf (port?) Tj /F1 10 Tf ( is a range check. No tag expansion, no heap object,) Tj T* 0 Tw (no allocator pressure \227 the port is the file descriptor, wrapped.) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 505.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 417.8236 cm +1 0 0 1 57.02362 485.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 391.8236 cm +1 0 0 1 57.02362 459.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 349.8236 cm +1 0 0 1 57.02362 417.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 331.8236 cm +1 0 0 1 57.02362 399.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 233.8236 cm +1 0 0 1 57.02362 301.8236 cm q q 1 0 0 1 0 0 cm @@ -4513,13 +6213,13 @@ Q Q Q q -1 0 0 1 57.02362 213.8236 cm +1 0 0 1 57.02362 281.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 135.0236 cm +1 0 0 1 57.02362 203.0236 cm q q 1 0 0 1 0 0 cm @@ -4539,47 +6239,47 @@ Q Q Q q -1 0 0 1 57.02362 79.02362 cm +1 0 0 1 57.02362 147.0236 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 - -endstream -endobj -92 0 obj -<< -/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 +1 0 0 1 57.02362 117.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 +1 0 0 1 57.02362 91.02362 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 +1 0 0 1 57.02362 73.02362 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 +1 0 0 1 57.02362 67.02362 cm Q q -1 0 0 1 57.02362 691.0236 cm +1 0 0 1 57.02362 67.02362 cm Q + +endstream +endobj +104 0 obj +<< +/Length 7914 +>> +stream +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 57.02362 643.0236 cm +1 0 0 1 57.02362 717.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -4601,10 +6301,10 @@ Q Q Q q -1 0 0 1 57.02362 637.0236 cm +1 0 0 1 57.02362 711.0236 cm Q q -1 0 0 1 57.02362 601.0236 cm +1 0 0 1 57.02362 675.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -4626,10 +6326,10 @@ Q Q Q q -1 0 0 1 57.02362 595.0236 cm +1 0 0 1 57.02362 669.0236 cm Q q -1 0 0 1 57.02362 559.0236 cm +1 0 0 1 57.02362 633.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -4651,25 +6351,25 @@ Q Q Q q -1 0 0 1 57.02362 541.0236 cm +1 0 0 1 57.02362 615.0236 cm Q q -1 0 0 1 57.02362 499.0236 cm +1 0 0 1 57.02362 573.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 473.0236 cm +1 0 0 1 57.02362 547.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 461.0236 cm +1 0 0 1 57.02362 535.0236 cm Q q -1 0 0 1 57.02362 449.0236 cm +1 0 0 1 57.02362 523.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -4685,41 +6385,41 @@ Q Q Q q -1 0 0 1 57.02362 449.0236 cm +1 0 0 1 57.02362 523.0236 cm Q q -1 0 0 1 57.02362 395.0236 cm +1 0 0 1 57.02362 469.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 329.0236 cm +1 0 0 1 57.02362 403.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 287.0236 cm +1 0 0 1 57.02362 361.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 255.8236 cm +1 0 0 1 57.02362 329.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 241.8236 cm +1 0 0 1 57.02362 315.8236 cm Q q -1 0 0 1 57.02362 241.8236 cm +1 0 0 1 57.02362 315.8236 cm Q q -1 0 0 1 57.02362 217.8236 cm +1 0 0 1 57.02362 291.8236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -4741,10 +6441,10 @@ Q Q Q q -1 0 0 1 57.02362 211.8236 cm +1 0 0 1 57.02362 285.8236 cm Q q -1 0 0 1 57.02362 187.8236 cm +1 0 0 1 57.02362 261.8236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -4766,10 +6466,10 @@ Q Q Q q -1 0 0 1 57.02362 181.8236 cm +1 0 0 1 57.02362 255.8236 cm Q q -1 0 0 1 57.02362 169.8236 cm +1 0 0 1 57.02362 243.8236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -4791,10 +6491,10 @@ Q Q Q q -1 0 0 1 57.02362 163.8236 cm +1 0 0 1 57.02362 237.8236 cm Q q -1 0 0 1 57.02362 151.8236 cm +1 0 0 1 57.02362 225.8236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -4816,70 +6516,70 @@ Q Q Q q -1 0 0 1 57.02362 133.8236 cm +1 0 0 1 57.02362 207.8236 cm Q q -1 0 0 1 57.02362 102.6236 cm +1 0 0 1 57.02362 176.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 82.62362 cm +1 0 0 1 57.02362 156.6236 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 - -endstream -endobj -93 0 obj -<< -/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 +1 0 0 1 57.02362 90.62362 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 + +endstream +endobj +105 0 obj +<< +/Length 6732 +>> +stream +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 57.02362 675.0236 cm +1 0 0 1 57.02362 741.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 +1 0 0 1 57.02362 675.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 +1 0 0 1 57.02362 645.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 561.0236 cm +1 0 0 1 57.02362 627.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 555.0236 cm +1 0 0 1 57.02362 621.0236 cm Q q -1 0 0 1 57.02362 555.0236 cm +1 0 0 1 57.02362 621.0236 cm Q q -1 0 0 1 57.02362 543.0236 cm +1 0 0 1 57.02362 609.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -4901,10 +6601,10 @@ Q Q Q q -1 0 0 1 57.02362 537.0236 cm +1 0 0 1 57.02362 603.0236 cm Q q -1 0 0 1 57.02362 525.0236 cm +1 0 0 1 57.02362 591.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -4926,10 +6626,10 @@ Q Q Q q -1 0 0 1 57.02362 519.0236 cm +1 0 0 1 57.02362 585.0236 cm Q q -1 0 0 1 57.02362 507.0236 cm +1 0 0 1 57.02362 573.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -4951,52 +6651,52 @@ Q Q Q q -1 0 0 1 57.02362 489.0236 cm +1 0 0 1 57.02362 555.0236 cm Q q -1 0 0 1 57.02362 471.0236 cm +1 0 0 1 57.02362 537.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 417.0236 cm +1 0 0 1 57.02362 483.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 375.0236 cm +1 0 0 1 57.02362 441.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 333.0236 cm +1 0 0 1 57.02362 399.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 291.0236 cm +1 0 0 1 57.02362 357.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 249.0236 cm +1 0 0 1 57.02362 315.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 243.0236 cm +1 0 0 1 57.02362 309.0236 cm Q q -1 0 0 1 57.02362 201.0236 cm +1 0 0 1 57.02362 267.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -5019,30 +6719,30 @@ Q Q Q q -1 0 0 1 57.02362 201.0236 cm +1 0 0 1 57.02362 267.0236 cm Q q -1 0 0 1 57.02362 171.0236 cm +1 0 0 1 57.02362 237.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 153.0236 cm +1 0 0 1 57.02362 219.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 121.8236 cm +1 0 0 1 57.02362 187.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 71.82362 cm +1 0 0 1 57.02362 137.8236 cm q q 1 0 0 1 0 0 cm @@ -5065,7 +6765,7 @@ Q endstream endobj -94 0 obj +106 0 obj << /Length 2147 >> @@ -5178,14 +6878,14 @@ Q endstream endobj -95 0 obj +107 0 obj << -/Length 1542 +/Length 1638 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 57.02362 511.8236 cm +1 0 0 1 57.02362 502.2236 cm q q 1 0 0 1 0 0 cm @@ -5195,10 +6895,10 @@ q .662745 .662745 .662745 RG .5 w .960784 .960784 .960784 rg -n -6 -6 480.0283 252 re B* +n -6 -6 480.0283 261.6 re B* Q q -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 +BT 1 0 0 1 0 241.6 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, extending across implementations through Scheme source) Tj T* (itself as the wire format. Three implementations, one language,) Tj T* (974 tests, ~17,000 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 @@ -5207,212 +6907,243 @@ Q endstream endobj -96 0 obj -<< -/Nums [ 0 97 0 R 1 98 0 R 2 99 0 R 3 100 0 R 4 101 0 R - 5 102 0 R 6 103 0 R 7 104 0 R 8 105 0 R 9 106 0 R - 10 107 0 R 11 108 0 R 12 109 0 R 13 110 0 R 14 111 0 R ] ->> -endobj -97 0 obj -<< -/S /D /St 1 ->> -endobj -98 0 obj -<< -/S /D /St 2 ->> -endobj -99 0 obj -<< -/S /D /St 3 ->> -endobj -100 0 obj -<< -/S /D /St 4 ->> -endobj -101 0 obj -<< -/S /D /St 5 ->> -endobj -102 0 obj -<< -/S /D /St 6 ->> -endobj -103 0 obj -<< -/S /D /St 7 ->> -endobj -104 0 obj -<< -/S /D /St 8 ->> -endobj -105 0 obj -<< -/S /D /St 9 ->> -endobj -106 0 obj -<< -/S /D /St 10 ->> -endobj -107 0 obj -<< -/S /D /St 11 ->> -endobj 108 0 obj << -/S /D /St 12 +/Nums [ 0 109 0 R 1 110 0 R 2 111 0 R 3 112 0 R 4 113 0 R + 5 114 0 R 6 115 0 R 7 116 0 R 8 117 0 R 9 118 0 R + 10 119 0 R 11 120 0 R 12 121 0 R 13 122 0 R 14 123 0 R + 15 124 0 R 16 125 0 R 17 126 0 R ] >> endobj 109 0 obj << -/S /D /St 13 +/S /D /St 1 >> endobj 110 0 obj << -/S /D /St 14 +/S /D /St 2 >> endobj 111 0 obj << +/S /D /St 3 +>> +endobj +112 0 obj +<< +/S /D /St 4 +>> +endobj +113 0 obj +<< +/S /D /St 5 +>> +endobj +114 0 obj +<< +/S /D /St 6 +>> +endobj +115 0 obj +<< +/S /D /St 7 +>> +endobj +116 0 obj +<< +/S /D /St 8 +>> +endobj +117 0 obj +<< +/S /D /St 9 +>> +endobj +118 0 obj +<< +/S /D /St 10 +>> +endobj +119 0 obj +<< +/S /D /St 11 +>> +endobj +120 0 obj +<< +/S /D /St 12 +>> +endobj +121 0 obj +<< +/S /D /St 13 +>> +endobj +122 0 obj +<< +/S /D /St 14 +>> +endobj +123 0 obj +<< /S /D /St 15 >> endobj +124 0 obj +<< +/S /D /St 16 +>> +endobj +125 0 obj +<< +/S /D /St 17 +>> +endobj +126 0 obj +<< +/S /D /St 18 +>> +endobj xref -0 112 +0 127 0000000000 65535 f 0000000061 00000 n -0000000143 00000 n -0000000250 00000 n -0001535099 00000 n -0001535208 00000 n -0001535320 00000 n -0001535435 00000 n -0001535608 00000 n -0001535789 00000 n -0001535894 00000 n -0001536187 00000 n -0001536393 00000 n -0001536599 00000 n -0001536805 00000 n -0001536883 00000 n -0001537089 00000 n -0001537295 00000 n -0001537501 00000 n -0001537707 00000 n -0001537913 00000 n -0001538091 00000 n -0001538316 00000 n -0001538522 00000 n -0001538700 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 -0001599535 00000 n -0001599741 00000 n -0001599847 00000 n -0001600102 00000 n -0001600177 00000 n -0001600327 00000 n -0001600437 00000 n -0001600602 00000 n -0001600797 00000 n -0001600914 00000 n -0001601032 00000 n -0001601174 00000 n -0001601374 00000 n -0001601509 00000 n -0001601645 00000 n -0001601815 00000 n -0001601939 00000 n -0001602070 00000 n -0001602192 00000 n -0001602388 00000 n -0001602505 00000 n -0001602632 00000 n -0001602762 00000 n -0001602954 00000 n -0001603073 00000 n -0001603207 00000 n -0001603345 00000 n -0001603490 00000 n -0001603673 00000 n -0001603791 00000 n -0001603948 00000 n -0001604086 00000 n -0001604234 00000 n -0001604384 00000 n -0001604522 00000 n -0001604657 00000 n -0001604808 00000 n -0001605000 00000 n -0001605107 00000 n -0001605297 00000 n -0001605453 00000 n -0001605617 00000 n -0001605749 00000 n -0001605879 00000 n -0001606021 00000 n -0001606144 00000 n -0001606269 00000 n -0001606378 00000 n -0001606541 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 +0000000157 00000 n +0000000264 00000 n +0001535113 00000 n +0001535222 00000 n +0001535334 00000 n +0001535449 00000 n +0001535622 00000 n +0001535803 00000 n +0001535908 00000 n +0001536201 00000 n +0001536407 00000 n +0001536613 00000 n +0001536819 00000 n +0001536897 00000 n +0001537103 00000 n +0001537309 00000 n +0001537515 00000 n +0001537599 00000 n +0001537805 00000 n +0001538011 00000 n +0001538217 00000 n +0001538424 00000 n +0001538602 00000 n +0001538828 00000 n +0001539035 00000 n +0001539242 00000 n +0001539420 00000 n +0001539594 00000 n +0001539802 00000 n +0001540042 00000 n +0001540248 00000 n +0001540420 00000 n +0001540653 00000 n +0001599629 00000 n +0001599939 00000 n +0001600258 00000 n +0001600465 00000 n +0001600572 00000 n +0001600827 00000 n +0001600902 00000 n +0001601052 00000 n +0001601162 00000 n +0001601327 00000 n +0001601522 00000 n +0001601639 00000 n +0001601757 00000 n +0001601899 00000 n +0001602099 00000 n +0001602234 00000 n +0001602383 00000 n +0001602513 00000 n +0001602683 00000 n +0001602807 00000 n +0001602938 00000 n +0001603060 00000 n +0001603256 00000 n +0001603373 00000 n +0001603500 00000 n +0001603630 00000 n +0001603815 00000 n +0001603962 00000 n +0001604117 00000 n +0001604289 00000 n +0001604442 00000 n +0001604585 00000 n +0001604740 00000 n +0001604885 00000 n +0001605068 00000 n +0001605186 00000 n +0001605343 00000 n +0001605481 00000 n +0001605629 00000 n +0001605779 00000 n +0001605917 00000 n +0001606052 00000 n +0001606203 00000 n +0001606396 00000 n +0001606516 00000 n +0001606638 00000 n +0001606828 00000 n +0001606984 00000 n +0001607148 00000 n +0001607280 00000 n +0001607410 00000 n +0001607552 00000 n +0001607675 00000 n +0001607800 00000 n +0001607909 00000 n +0001608093 00000 n +0001612893 00000 n +0001621330 00000 n +0001628317 00000 n +0001637109 00000 n +0001645942 00000 n +0001657747 00000 n +0001669062 00000 n +0001678414 00000 n +0001687586 00000 n +0001694705 00000 n +0001704095 00000 n +0001712804 00000 n +0001726271 00000 n +0001737193 00000 n +0001745160 00000 n +0001751945 00000 n +0001754145 00000 n +0001755836 00000 n +0001756066 00000 n +0001756101 00000 n +0001756136 00000 n +0001756171 00000 n +0001756206 00000 n +0001756241 00000 n +0001756276 00000 n +0001756311 00000 n +0001756346 00000 n +0001756381 00000 n +0001756417 00000 n +0001756453 00000 n +0001756489 00000 n +0001756525 00000 n +0001756561 00000 n +0001756597 00000 n +0001756633 00000 n +0001756669 00000 n trailer << /ID -[<8aea0891e8ebfbc48b60770ef7c0f271><8aea0891e8ebfbc48b60770ef7c0f271>] +[<32a89959b93d5a53476ae9ef34150649><32a89959b93d5a53476ae9ef34150649>] % ReportLab generated PDF document -- digest (opensource) -/Info 35 0 R -/Root 34 0 R -/Size 112 +/Info 39 0 R +/Root 38 0 R +/Size 127 >> startxref -1718695 +1756705 %%EOF diff --git a/whitepaper/uncommonlisp-whitepaper.rst b/whitepaper/uncommonlisp-whitepaper.rst index bc348f2..074bfb1 100644 --- a/whitepaper/uncommonlisp-whitepaper.rst +++ b/whitepaper/uncommonlisp-whitepaper.rst @@ -13,7 +13,7 @@ .. .. This software contributes to that vision by proving that feedback .. (the computational primitive of continuations) composes into a universal -.. execution model: a complete Scheme in four implementations (Python, +.. execution model: a complete Scheme in three implementations (Python, .. C with x86_64 JIT, pure assembly), with a bytecode VM, full .. continuations, machine state serialization, & an antimoad scanner .. that catches the defects our training data encodes, @@ -56,13 +56,23 @@ 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. +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. -**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. +**uncommonlisp** proves this by implementing R7RS Scheme three ways: + +- **Python bytecode VM** — 3,678 lines, full first-class continuations, JSON portal, reference implementation +- **C interpreter + x86_64 JIT** — ~9,000 lines, 7--10× faster than CPython on recursive workloads, JSON portal +- **Pure x86_64 assembly** — 4,455 lines, 22 KB stripped binary, zero external dependencies, 79 builtins, 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. + +**The numbers.** The asm implementation saves + resumes 4 variables across two processes in **1.5 ms** (binary portal) or **1.6 ms** (S-expression portal). Python round-trip on the same task: 260 ms. A 160× gap from the same language, same tests, same wire format. + +974+ verified assertions pass identically across the three implementations (571 Python unit, 131 asm, 189 shared Python+C functional, 83 C unit). Every implementation consumes every format it can reach; mismatch cases (wrong format, truncated input, missing file, corrupt header) degrade gracefully with ``#f`` or a clean error. 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``. -Feedback is the primitive. Continuations are the mechanism. One file is the proof. +Feedback is the primitive. Continuations are its mechanism in time. Portals are its mechanism across time. S-expressions are its mechanism across implementations. One file is the proof — by three translations. 1. The Problem: Interpreters That Cannot Feed Back @@ -78,7 +88,7 @@ Scheme discovered this in 1975 with ``call-with-current-continuation``. But most 2. Architecture: One File, Two Evaluators ------------------------------------------ -uncommonlisp implements two evaluation strategies in a single 3,261-line Python file: +uncommonlisp implements two evaluation strategies in a single 3,678-line Python file: **Tree-walking interpreter** (``leval``): The default mode. Walks the AST directly, handles all forms including macro definitions, record types, & dynamic features. Suitable for interactive development & complex metaprogramming. @@ -248,11 +258,32 @@ Every control flow pattern reduces to a continuation operation: - **Loop**: tail-call feeds the function back to itself - **Generator**: ``call/cc`` feeds a value out, saves a resumption point, feeds control back in on next call - **Exception**: ``call/cc`` feeds control to a handler registered via ``dynamic-wind`` -- **Checkpoint**: portal serializes the continuation to JSON, feeds the machine state to storage +- **Checkpoint**: portal serializes the continuation, feeds the machine state to storage - **Migration**: portal deserializes on another machine, feeds the continuation back to a new VM +- **Cross-impl exchange**: S-expression serialization feeds bindings across implementations that share no memory layout One primitive. Every pattern. +4.3 Three Scopes of Feedback +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The single word "feedback" covers three nested scopes, each giving rise to one of our core abstractions: + +.. table:: + :widths: 18 28 28 26 + + =============== ========================= ========================= ========================== + Scope Mechanism Unit of travel Implementation + =============== ========================= ========================= ========================== + Within process ``call/cc``, tail-call continuation (live) explicit frame stack + Across process portal (JSON or binary) VM state + continuation graph serializer + Across impl source-as-interchange bindings (as data) the reader + =============== ========================= ========================= ========================== + +Within a single VM, a continuation is the unit — the whole call stack, captured & passed. Across processes on the same machine, a portal is the unit — the whole heap or VM state, serialized to a file, resumed elsewhere. Across implementations that share no binary compatibility, Scheme source itself is the unit: ``(define x 42)`` travels because every parser already knows how to receive it. + +The same abstraction, at three scopes. No new primitive at any level. This is what "feedback is all you need" actually means once you extend it past the process boundary. + 5. Optimizations ----------------- @@ -349,50 +380,153 @@ The important comparison is not uncommonlisp vs CPython (different languages), b - **hash-table**: 1,000 ``set!`` + ``ref`` operations. Tests Python dict interop overhead -7. Portal: Machine State Serialization +7. Portal: Feedback Across Time ---------------------------------------- -Portal serializes the complete VM state (environment, continuation stack, instruction pointer, value stack) to JSON & resumes execution on another machine. +A continuation is feedback within a process. A portal is feedback across processes. Same primitive, different scope: capture machine state, serialize it, reload it elsewhere, resume. uncommonlisp ships three portal formats with different tradeoffs & constituencies. -7.1 Serialization -^^^^^^^^^^^^^^^^^^ +.. table:: + :widths: 22 22 14 14 14 14 -The ``_PortalSerializer`` performs graph-aware serialization: + ====================== ================================ ======== ======== ======== =========== + Format Consumers Size Save Load Resumes + ====================== ================================ ======== ======== ======== =========== + **S-expression** Python, C, asm — all three ~310 B 0.9 ms 0.7 ms bindings + **JSON (graph-aware)** Python, C ~26 KB 3.1 ms — full VM + k + **Binary heap dump** asm only ~10 KB 0.1 ms 0.1 ms asm heap + ====================== ================================ ======== ======== ======== =========== -- Tracks ``id(obj) → ref_id`` for object identity (handles shared references & cycles) +Times measured on a 4-binding workload (int + list + string + fib(30) result) excluding process startup. "k" = continuation. + +7.1 S-Expression Portal — the Portable One +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The most boring format is the most portable. An S-expression portal is a sequence of ``define`` forms: + +:: + + ;; uncommonlisp portable state + (define my-int 42) + (define my-list '(1 2 3 4 5 6 7 8 9 10)) + (define my-str "hello world") + (define my-result 832040) + +Every Scheme implementation in the world can already read this. No schema, no decoder, no version field. The file is a Scheme program; loading it is evaluating it. + +**The key insight: the language IS the interchange format.** We did not design this. R. Kent Dybvig didn't. John McCarthy didn't. It is a structural consequence of homoiconicity: if the syntax of the language is the syntax of its data structures, then data serialization is language serialization. Portability across implementations is free — it arrives with the parser. + +Producer side: assemble the file with ``(display ...)`` & ``(write ...)`` to an output port. Consumer side: ``(load "file.sexp")``. Both sides exist in every implementation, giving us a 3×3 matrix of valid exchanges. + +7.2 Cross-Implementation Exchange Matrix +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. table:: + :widths: 12 14 14 14 + + ============ ========= ========= ========= + Producer → Python C asm + Consumer ↓ + ============ ========= ========= ========= + Python ✓ ✓ ✓ + C ✓ ✓ ✓ + asm ✓ ✓ ✓ + ============ ========= ========= ========= + +9 of 9. Verified by ``tests/portal-cross-test.sh``. Same file, same semantics, regardless of which process produced it. + +This matters because it defeats the "version lock-in" trap. If the JSON portal were the only option, a Python 3.15 producer could emit structures a C consumer couldn't parse. With S-expression portals, the only dependency is a parser that handles the subset of forms in the file. Every implementation already has one. + +7.3 JSON Portal — Graph-Aware, Continuation-Preserving +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +When you need to preserve shared references, cycles, closures, or a *live continuation*, S-expressions aren't enough. The JSON portal (Python & C) performs graph-aware serialization: + +- Tracks ``id(obj) → ref_id`` for object identity (handles shared refs & cycles) - Serializes environments as chains of binding dictionaries with parent pointers - Serializes compiled procedures as ``CodeObj`` + captured environment - Serializes continuations as the full frame stack + machine state - Skips builtins (reconstructed from the prelude on resume) -7.2 Deserialization -^^^^^^^^^^^^^^^^^^^^ +Deserialization is two-pass: shell pass creates empty object shells & assigns reference IDs, fill pass populates pointers & values. This handles the closure-that-captures-itself pattern cleanly. -The ``_PortalDeserializer`` performs two-pass reconstruction: - -1. **Shell pass**: Create empty object shells & assign reference IDs -2. **Fill pass**: Populate pointers, values, & environment chains - -This handles circular references (e.g., a closure whose environment contains a reference to the closure itself). - -7.3 Checkpoint & Resume -^^^^^^^^^^^^^^^^^^^^^^^^^ - -During VM execution, ``portal-checkpoint!`` triggers at ``OP_JUMP`` & ``OP_TAIL_CALL`` instructions. When triggered: - -1. Capture the current continuation (same mechanism as ``call/cc``) -2. Serialize the continuation + environment to a ``.portal`` file -3. Continue execution (or halt, depending on the use case) - -Resumption: +During VM execution, ``portal-checkpoint!`` triggers at ``OP_JUMP`` & ``OP_TAIL_CALL`` instructions, capturing the current continuation, serializing it to a ``.portal`` file, & continuing. Resumption restores the saved state & continues execution from the exact instruction where the checkpoint occurred. :: python3 uncommonlisp.py --portal-resume state.portal -The VM deserializes the saved state, reconstructs the continuation, & resumes execution from the exact instruction where the checkpoint occurred. The computation does not need to restart from the beginning. +The computation does not need to restart from the beginning. -7.4 Use Case: Distributed Primality Testing +7.4 Binary Heap Dump — the Fast One +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The asm implementation ships a direct-dump portal: write the raw heap bytes, the ``r14`` (env) & ``r15`` (bump pointer) registers, the heap base address, & a magic header. No parsing, no encoding. + +:: + + bi_portal_save: + # Magic | heap_size | heap_base | r14 | r15 | reserved | heap_bytes + + bi_portal_resume: + # Read 48-byte header, verify magic + sanity, + # mmap MAP_FIXED at saved heap_base so pointers stay valid, + # read heap bytes into fixed-address region, + # restore r14/r15. + +Sub-millisecond save & resume. The MAP_FIXED trick is why it works across processes: because every pointer inside the heap is an absolute address, resuming at a different address would require relocation. Mapping at the same address keeps pointers live. + +Constraints: same architecture, same binary layout, same process model. An asm binary portal written on one box resumes on another x86_64 Linux box running the same asm binary. It does not resume on a rebuilt binary — the BSS-resident symbol table ``sym_table`` is not in the heap dump, so interned symbols would need to be reinterned. That's the price of trivial serialization. + +7.5 Cross-Process Benchmarks +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Producer process A saves state to a file; consumer process B starts fresh, loads the file, continues. Wall-clock time for both processes end-to-end, 50 iterations, same-laptop: + +.. table:: + :widths: 36 16 + + =================================== ========== + Pair (producer → consumer) Time/iter + =================================== ========== + Python → Python (sexp) 260 ms + C → C (sexp) 6 ms + **asm → asm (sexp)** **1.6 ms** + **asm → asm (binary portal)** **1.5 ms** + Python → C (sexp) 133 ms + Python → asm (sexp) 145 ms + C → Python (sexp) 154 ms + C → asm (sexp) 4.1 ms + asm → Python (sexp) 167 ms + asm → C (sexp) 4.6 ms + =================================== ========== + +The asm→asm cross-process is ~160× faster than Python→Python. The binary & S-expression portals are within 10% of each other on this workload — the bottleneck is process startup, not serialization. For larger heaps the binary format pulls further ahead; for portability, S-expression always wins. + +7.6 Mismatch Cases: Graceful Degradation +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +A usable persistence layer fails well. What happens when the consumer meets unexpected input? + +.. table:: + :widths: 38 14 14 14 + + ==================================== =========== =========== =========== + Input Python C asm + ==================================== =========== =========== =========== + Empty file continue continue continue + Missing file ``file not ``error: ``#f`` + + found: …`` …`` continue + Truncated sexp (``(define x``) ``error: ``error: continue + unclosed`` unclosed`` (benign) + Binary portal fed to ``(load)`` text-file reader symbol + error error errors + sexp file fed to ``portal-resume`` — — ``#f`` + Truncated binary portal — — ``#f`` + ==================================== =========== =========== =========== + +All defects surfaced & fixed during benchmark development: an asm segfault on ``(define x)`` without a value (now binds to ``VOID``), an asm portal-resume that accepted short headers (now verifies ``sys_read`` returned a full 48 bytes & sanity-checks heap metadata), a Python ``file not found`` error reporting the outer script path instead of the inner missing file (now uses ``FileNotFoundError.filename``). Graceful degradation is not free; it is tested. + +7.7 Use Case: Distributed Primality Testing ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :: @@ -409,7 +543,7 @@ The VM deserializes the saved state, reconstructs the continuation, & resumes ex (define result (prime? 1000000007)) -Machine A starts the computation. Every 10,000 iterations, it writes a checkpoint. Machine B picks up the ``.portal`` file & continues from the last checkpoint. The computation migrates without either machine needing to know about the other. Feedback (the continuation) carries the entire execution context. +Machine A starts the computation. Every 10,000 iterations, it writes a checkpoint. Machine B picks up the ``.portal`` file & continues from the last checkpoint. The computation migrates without either machine needing to know about the other. Feedback — the continuation — carries the entire execution context. 8. The EML Universality Proof @@ -526,7 +660,7 @@ uncommonlisp implements a near-complete R7RS-small Scheme: **Standard library** (``stdlib.lsp``, 385 lines): Additional macros (``swap!``, ``fluid-let``, ``while``, ``dotimes``), utility functions, simple object system, SRFI-2/8/64 test framework. -**Test suite**: 529 tests covering lexing, parsing, special forms, bytecode compilation, macros (hygienic & procedural), continuations, generators, record types, modules, arithmetic, higher-order functions, error handling, & portal serialization. +**Test suite**: 974 verified assertions covering lexing, parsing, special forms, bytecode compilation, macros (hygienic & procedural), continuations, generators, record types, modules, arithmetic, higher-order functions, error handling, portal serialization, cross-implementation portal exchange, file I/O parity, & graceful degradation on mismatched or corrupt input. 10. Relationship to Companion Papers @@ -549,7 +683,7 @@ uncommonlisp forms one piece of a larger permacomputer machine learning stack: uncommonlisp 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 uncommonlisp's VM, with ``call/cc`` providing the state machine transitions & portal providing persistence. -11. Four Implementations, One Language +11. Three Implementations, One Language --------------------------------------- *"A diagram is worth 10,000 words."* — russell@unturf.com @@ -557,37 +691,63 @@ uncommonlisp provides the runtime layer: a language that can checkpoint its own 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 10 10 10 10 10 + :widths: 24 8 10 10 11 10 9 - ===================== ======= ========== ========= =========== ============ ============== - 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 - ===================== ======= ========== ========= =========== ============ ============== + ===================== ====== ========== ========= =========== ========= ============== + Implementation Lines ack(3,4) fib(35) sum-to(50k) Binary Dependencies + ===================== ====== ========== ========= =========== ========= ============== + C + x86_64 JIT ~9k 0.19 ms 0.09 ms 0.55 ms 205 KB libc + CPython (reference) — 1.3 ms 0.006 ms 5.5 ms — Python 3 + C interpreter ~9k 20 ms 0.06 ms 109 ms 205 KB libc + Python bytecode VM 3,678 149 ms 0.75 ms 437 ms — Python 3 + x86_64 assembly (†) 4,455 8 ms 0.6 ms 43 ms 22 KB none + ===================== ====== ========== ========= =========== ========= ============== -All benchmarks measured in-process (no startup overhead) on the same machine. Assembly times (\*) include process startup + tokenizer + parser. +All C & Python benchmarks measured in-process (no startup overhead). Assembly times (†) include full process lifetime: startup + tokenizer + parser + eval. "—" = not applicable / interpreted. -**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 JIT runs Scheme faster than CPython runs Python.** ``ack(3,4)`` completes in 0.19 ms (JIT) vs 1.3 ms (CPython) — 7× faster. ``sum-to(50000)`` completes in 0.55 ms (JIT) vs 5.5 ms (CPython) — 10× 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 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. +**The assembly implementation proves the language runs on bare metal.** 4,455 lines of GNU assembler, **22 KB stripped binary**, zero external dependencies. Only seven Linux syscalls (``read``, ``write``, ``open``, ``close``, ``lseek``, ``mmap``, ``munmap``, ``exit``). A bump allocator, tag-in-low-3-bits values, **79 builtins** (including ``load``, ``open-output-file``, ``close-port``, ``port?``, port-aware ``display``/``write``/``newline``, ``write-file``, ``file->string``, ``portal-save``, ``portal-resume``), & TCO via ``jmp``. It runs ``(ack 3 4) = 125`` & ``(fib 35) = 9227465`` correctly — 2.5× faster than the C interpreter on recursive workloads because hand-written assembly avoids C's function call overhead for eval dispatch. -**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. +**The bytecode VM delivers 7--19× 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 ^^^^^^^^^^^^^^^^^^^^ -943 verified assertions across all implementations: +**974 verified assertions** across all implementations, all green under ``make test-all``: -- 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) +- Python unit + integration: **571 tests** (``tests.py``) +- C unit + integration + JIT + continuations + portal: **83 tests** (``c/test.c``) +- Assembly unit + integration + functional: **131 tests** (``asm/test.sh``) +- Shared functional (same ``.lsp`` in Python + C): **189 tests** (``tests/functional.lsp``) -All pass via ``make test-all``. +The shared functional suite matters: it runs byte-identical Scheme source through two different runtimes & compares output. Python & C agree 189 times per run. When they disagree, that tells us something specific & actionable. + +Cross-implementation portal exchange is verified separately: ``tests/portal-cross-test.sh`` runs 9 producer×consumer combinations. All 9 green. + +11.2 File I/O Parity +^^^^^^^^^^^^^^^^^^^^^ + +All three implementations share the same minimal file I/O vocabulary — discovered necessary while building the cross-impl portal: + +.. table:: + :widths: 30 20 12 12 12 + + ============================= ===================== ====== ===== ===== + Builtin Semantics Py C asm + ============================= ===================== ====== ===== ===== + ``(load "path")`` read + eval forms ✓ ✓ ✓ + ``(open-output-file p)`` open, return port ✓ ✓ ✓ + ``(close-port p)`` close port ✓ ✓ ✓ + ``(port? x)`` port predicate ✓ ✓ ✓ + ``(display v [port])`` to stdout or port ✓ ✓ ✓ + ``(write v [port])`` quoted / readable ✓ ✓ ✓ + ``(newline [port])`` line break ✓ ✓ ✓ + ``(write-file path str)`` bytes in, #t/#f ✓ ✓ ✓ + ``(file->string path)`` read whole file ✓ ✓ ✓ + ============================= ===================== ====== ===== ===== + +The asm port representation deserves a note. Because all three tag bits are consumed by the existing value types (int/pair/sym/closure/builtin/special/string/vector), we encode ports as ``SPECIAL`` values ≥ 1000: ``port_val = ((PORT_SPECIAL_BASE + fd) << 3) | TAG_SPECIAL``. Extraction is ``fd = (val >> 3) - PORT_SPECIAL_BASE``. ``port?`` is a range check. No tag expansion, no heap object, no allocator pressure — the port is the file descriptor, wrapped. 12. MOAD Audit: Fixing What We Built @@ -753,8 +913,9 @@ License This software contributes to that vision by proving that feedback (the computational primitive of continuations) composes into a universal - execution model. Four implementations, one language, 836 tests, 12,774 - lines. Code is seeds to sprout on any abandoned technology. + execution model, extending across implementations through Scheme source + itself as the wire format. Three implementations, one language, + 974 tests, ~17,000 lines. Code is seeds to sprout on any abandoned technology. Learn more: https://www.permacomputer.com