<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Programming Simplicity]]></title><description><![CDATA[Exploring simplicity in programming]]></description><link>https://programmingsimplicity.substack.com</link><image><url>https://substackcdn.com/image/fetch/$s_!eSyZ!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d69eba9-d5d3-4387-a046-9b881b00bd45_131x131.png</url><title>Programming Simplicity</title><link>https://programmingsimplicity.substack.com</link></image><generator>Substack</generator><lastBuildDate>Fri, 26 Jun 2026 21:48:02 GMT</lastBuildDate><atom:link href="https://programmingsimplicity.substack.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Paul Tarvydas]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[programmingsimplicity@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[programmingsimplicity@substack.com]]></itunes:email><itunes:name><![CDATA[Paul Tarvydas]]></itunes:name></itunes:owner><itunes:author><![CDATA[Paul Tarvydas]]></itunes:author><googleplay:owner><![CDATA[programmingsimplicity@substack.com]]></googleplay:owner><googleplay:email><![CDATA[programmingsimplicity@substack.com]]></googleplay:email><googleplay:author><![CDATA[Paul Tarvydas]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Separating Architecture From Implementation]]></title><description><![CDATA[2026-06-27]]></description><link>https://programmingsimplicity.substack.com/p/separating-architecture-from-implementation</link><guid isPermaLink="false">https://programmingsimplicity.substack.com/p/separating-architecture-from-implementation</guid><dc:creator><![CDATA[Paul Tarvydas]]></dc:creator><pubDate>Fri, 26 Jun 2026 12:52:26 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!eSyZ!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d69eba9-d5d3-4387-a046-9b881b00bd45_131x131.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>With our current programming languages it is difficult to separate architecture from implementation.</p><p>The reason for this is just a minor detail: functions are implemented on hardware using the CALL/RETURN instruction.</p><p>The implementation is that the CALLer suspends (blocks) until the callee returns something. This minor detail winds deep dependencies throughout code and makes it difficult to reason about what is going on.</p><p>The best way to break the dependency is to separate - control-flow wise - the caller from the callee, i.e. by using pure message sending (instead of impure message passing, as is implemented by CALL/RETURN and calling conventions). I built this into Parts Based Programming (PBP) through instinct.</p><p>Hardware ICs work this way, too. If actions need to be synchronized, the are explicitly, externally synchronized by the architect, not vagaries of the hardware such as CALL/RETURN (and cache coherency).</p><h1>Further Reading / Viewing</h1><ul><li><p><a href="https://www.youtube.com/playlist?list=PLHh2_dCKBPjbBN2R8xwBiS4nHlo5iQjqS">PBP basics (playlist)</a></p></li><li><p><a href="https://www.youtube.com/playlist?list=PLHh2_dCKBPjbBN2R8xwBiS4nHlo5iQjqS">PBP Cookbook (playlist)</a></p></li><li><p><a href="https://www.youtube.com/playlist?list=PLHh2_dCKBPjYBmubkBfn0LSbDMRKsr9Ui">Towards PBP (playlist)</a></p></li><li><p><a href="https://programmingsimplicity.substack.com/p/building-software-using-black-boxes?r=1egdky">Building Software Using Black Boxes</a></p></li><li><p><a href="https://programmingsimplicity.substack.com/p/pbp-black-box-abstraction-port-fan?r=1egdky">PBP Black Box Abstraction, Ports, Fan-out, Fan-in</a></p></li><li><p><a href="https://youtu.be/EFTzFA82YRc?t=330">how to install PBP</a></p></li><li><p><a href="https://youtu.be/EFTzFA82YRc">Hello World and simple parallelism in PBP</a></p></li></ul><p>See also, the essays, blogs and videos listed below</p><h1>See Also</h1><p><em>Substack</em>: <a href="http://paultarvydas.substack.com/">paultarvydas.s. bstack.com</a><br><em>(earlier) Blog:</em> <a href="http://guitarvydas.github.io/">guitarvydas.github.io</a><br><em>Videos</em>: <a href="https://www.youtube.com/@programmingsimplicity2980">https://www. youtube.com/@programmingsimplicity2980</a><br><em>Email</em>: <a href="mailto:ptcomputingsimplicity@gmail.com">ptcomputingsimplicity@gmail.com</a><br><em>Discord</em>: <a href="https://discord.gg/65YZUh6Jpq">https://discord.gg/65YZUh6J. q</a><br><em>Leanpub</em>: <a href="https://leanpub.com/u/paul-tarvydas">https:. /leanpub.com/u/paul-tarvydas</a><br><em>Twitter</em>: @paul_tarvydas<br><em>Bluesky:</em> @paultarvydas.bsky.social<br><em>Mastodon:</em> @paultarvydas<br><em>References:</em> <a href="https://guitarvydas.github.io/2024/01/06/References.html">https://guitarvydas.github.io/2024/01/06/References.html</a></p><p><em>Paid subscriptions are a voluntary way to support this work.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/p/separating-architecture-from-implementation/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/p/separating-architecture-from-implementation/comments"><span>Leave a comment</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/p/separating-architecture-from-implementation?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/p/separating-architecture-from-implementation?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/subscribe?"><span>Subscribe now</span></a></p>]]></content:encoded></item><item><title><![CDATA[Concurrency (Part 2 of 2)]]></title><description><![CDATA[2026-06-24]]></description><link>https://programmingsimplicity.substack.com/p/concurrency-part-2-of-2</link><guid isPermaLink="false">https://programmingsimplicity.substack.com/p/concurrency-part-2-of-2</guid><dc:creator><![CDATA[Paul Tarvydas]]></dc:creator><pubDate>Wed, 24 Jun 2026 13:56:58 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!eSyZ!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d69eba9-d5d3-4387-a046-9b881b00bd45_131x131.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>&#8220;Concurrency&#8221; is a concept tuned for allowing multiple functions to operate independently in the synchronous, sequential paradigm. It essentially uses a &#8220;trick&#8221; to allow this to happen - it assumes that the multiple functions are internally synchronized and it makes them run in a sequential manner.</p><p>This &#8220;trick&#8221; is useful for allowing us to think in terms of computation, but it doesn&#8217;t address asynchronous systems. Hence, it only addresses about 5% of reality (this number is pulled out of thin air and is not measured, yet, I base it on the fact that cosmology is based on the functional paradigm which pushes aside 95% of the problem that can&#8217;t be addressed in functional form, and calls it &#8220;dark matter&#8221;)</p><ul><li><p>only simulates parallelism, is not full parallelism</p></li><li><p>teaching this has obscured the fact that concurrency is not true parallelism - people think that they are getting parallelism when using &#8220;thread libraries&#8221;, but they are only getting time-slicing, i.e. multiple functions running on a single computer in a synchronous - not asynchronous - manner.</p></li><li><p>micro-managed sharing of memory at the cell level instead of message-passing between isolated components</p></li><li><p>upper-level, explicit message-passing vs. lower-level, implicit memory sharing</p></li><li><p>the simplest, most efficient system would be a computer that is running exactly one program and not time-sharing the same computer with other programs</p><ul><li><p>this would remove the need for a lot of internal complexity, i.e. &#8220;thread safety&#8221;, since the single program does not share memory with any other program, hence, the compiler and the programming language could be massively simplified</p></li></ul></li><li><p>If we imagine multiple such devices running single programs, but not sharing memory, then the best way for them to communicate and synchronize would be to pass message packets to one another</p><ul><li><p>This is what PBP does - it creates &#8220;parts&#8221; that are self-contained and do not share memory with other parts, it uses <code>send(...)</code> to explicitly send message packets (&#8220;mevents&#8221;) between parts.</p></li><li><p>You are forced to write code that contains explicit message passing, instead of writing code that relies on implicit memory sharing. This maps to asynchronous reality better. # See Also</p></li></ul></li></ul><p><em>Email</em>: <a href="mailto:ptcomputingsimplicity@gmail.com">ptcomputingsimplicity@gmail.com</a><br><em>Substack</em>: <a href="http://paultarvydas.substack.com/">paultarvydas.s. bstack.com</a><br><em>Videos</em>: <a href="https://www.youtube.com/@programmingsimplicity2980">https://www. youtube.com/@programmingsimplicity2980</a><br><em>Discord</em>: <a href="https://discord.gg/65YZUh6Jpq">https://discord.gg/65YZUh6J. q</a><br><em>Leanpub</em>: <a href="https://leanpub.com/u/paul-tarvydas">https:. /leanpub.com/u/paul-tarvydas</a><br><em>Twitter</em>: @paul_tarvydas<br><em>Bluesky:</em> @paultarvydas.bsky.social<br><em>Mastodon:</em> @paultarvydas<br><em>(earlier) Blog:</em> <a href="http://guitarvydas.github.io/">guitarvydas.github.io</a><br><em>References:</em> <a href="https://guitarvydas.github.io/2024/01/06/References.html">https://guitarvydas.github.io/2024/01/06/References.html</a></p><p><em>Paid subscriptions are a voluntary way to support this work.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/p/concurrency-part-2-of-2/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/p/concurrency-part-2-of-2/comments"><span>Leave a comment</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/p/concurrency-part-2-of-2?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/p/concurrency-part-2-of-2?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/subscribe?"><span>Subscribe now</span></a></p>]]></content:encoded></item><item><title><![CDATA[Concurrency (Part 1 of 2)]]></title><description><![CDATA[2026-06-24]]></description><link>https://programmingsimplicity.substack.com/p/concurrency-part-1-of-2</link><guid isPermaLink="false">https://programmingsimplicity.substack.com/p/concurrency-part-1-of-2</guid><dc:creator><![CDATA[Paul Tarvydas]]></dc:creator><pubDate>Wed, 24 Jun 2026 13:55:57 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!t07n!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59b68861-c97c-44d7-9d21-8c2d0108a28e_1653x873.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Simplified sketches that show the difference between concurrency and pure message passing.</p><h2>Computer With Concurrency</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!t07n!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59b68861-c97c-44d7-9d21-8c2d0108a28e_1653x873.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!t07n!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59b68861-c97c-44d7-9d21-8c2d0108a28e_1653x873.png 424w, https://substackcdn.com/image/fetch/$s_!t07n!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59b68861-c97c-44d7-9d21-8c2d0108a28e_1653x873.png 848w, https://substackcdn.com/image/fetch/$s_!t07n!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59b68861-c97c-44d7-9d21-8c2d0108a28e_1653x873.png 1272w, https://substackcdn.com/image/fetch/$s_!t07n!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59b68861-c97c-44d7-9d21-8c2d0108a28e_1653x873.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!t07n!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59b68861-c97c-44d7-9d21-8c2d0108a28e_1653x873.png" width="1456" height="769" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/59b68861-c97c-44d7-9d21-8c2d0108a28e_1653x873.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:769,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!t07n!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59b68861-c97c-44d7-9d21-8c2d0108a28e_1653x873.png 424w, https://substackcdn.com/image/fetch/$s_!t07n!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59b68861-c97c-44d7-9d21-8c2d0108a28e_1653x873.png 848w, https://substackcdn.com/image/fetch/$s_!t07n!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59b68861-c97c-44d7-9d21-8c2d0108a28e_1653x873.png 1272w, https://substackcdn.com/image/fetch/$s_!t07n!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59b68861-c97c-44d7-9d21-8c2d0108a28e_1653x873.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>A simplified sketch. Note that functions (A-I) might be one function or a tightly coupled thread of functions calling functions (which is really just one big function).</p><p>Not shown: all sorts of complicated extra code that belongs to the dispatcher and operating system.</p><p>Threads run more slowly than they could due to time-slicing and due to operating system overhead.</p><p>This only <em>simulates</em> parallelism using a mechanism that is unrealistic for geographically distributed systems, i.e. memory sharing. In addition, the simulation assumes that the processes are automagically synchronized (via memory sharing and cache coherency and extra hardware).</p><p>Each program (functions A-I) is actually a state machine. Programmers do not get to easily control and architect this behaviour. Context switching is performed by algorithms buried in the operating systems.</p><h2>System With Pure Message Passing</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ya6x!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8d4c956-5d84-4f16-ac35-16a7ed5e15b7_1773x1113.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ya6x!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8d4c956-5d84-4f16-ac35-16a7ed5e15b7_1773x1113.png 424w, https://substackcdn.com/image/fetch/$s_!ya6x!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8d4c956-5d84-4f16-ac35-16a7ed5e15b7_1773x1113.png 848w, https://substackcdn.com/image/fetch/$s_!ya6x!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8d4c956-5d84-4f16-ac35-16a7ed5e15b7_1773x1113.png 1272w, https://substackcdn.com/image/fetch/$s_!ya6x!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8d4c956-5d84-4f16-ac35-16a7ed5e15b7_1773x1113.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ya6x!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8d4c956-5d84-4f16-ac35-16a7ed5e15b7_1773x1113.png" width="1456" height="914" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a8d4c956-5d84-4f16-ac35-16a7ed5e15b7_1773x1113.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:914,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ya6x!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8d4c956-5d84-4f16-ac35-16a7ed5e15b7_1773x1113.png 424w, https://substackcdn.com/image/fetch/$s_!ya6x!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8d4c956-5d84-4f16-ac35-16a7ed5e15b7_1773x1113.png 848w, https://substackcdn.com/image/fetch/$s_!ya6x!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8d4c956-5d84-4f16-ac35-16a7ed5e15b7_1773x1113.png 1272w, https://substackcdn.com/image/fetch/$s_!ya6x!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8d4c956-5d84-4f16-ac35-16a7ed5e15b7_1773x1113.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Not shown: code that polls (or reacts to) incoming messages on input ports.</p><p>This can be simulated on a single development system by ensuring that programs cannot share memory.</p><p>Each program gets almost 100% of each separate CPU, hence, runs more quickly than on time-shared machines. # See Also</p><p><em>Email</em>: <a href="mailto:ptcomputingsimplicity@gmail.com">ptcomputingsimplicity@gmail.com</a><br><em>Substack</em>: <a href="http://paultarvydas.substack.com/">paultarvydas.s. bstack.com</a><br><em>Videos</em>: <a href="https://www.youtube.com/@programmingsimplicity2980">https://www. youtube.com/@programmingsimplicity2980</a><br><em>Discord</em>: <a href="https://discord.gg/65YZUh6Jpq">https://discord.gg/65YZUh6J. q</a><br><em>Leanpub</em>: <a href="https://leanpub.com/u/paul-tarvydas">https:. /leanpub.com/u/paul-tarvydas</a><br><em>Twitter</em>: @paul_tarvydas<br><em>Bluesky:</em> @paultarvydas.bsky.social<br><em>Mastodon:</em> @paultarvydas<br><em>(earlier) Blog:</em> <a href="http://guitarvydas.github.io/">guitarvydas.github.io</a><br><em>References:</em> <a href="https://guitarvydas.github.io/2024/01/06/References.html">https://guitarvydas.github.io/2024/01/06/References.html</a></p><p><em>Paid subscriptions are a voluntary way to support this work.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/p/concurrency-part-1-of-2/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/p/concurrency-part-1-of-2/comments"><span>Leave a comment</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/p/concurrency-part-1-of-2?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/p/concurrency-part-1-of-2?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/subscribe?"><span>Subscribe now</span></a></p>]]></content:encoded></item><item><title><![CDATA[Repeating Architectural Patterns]]></title><description><![CDATA[2026-06-24]]></description><link>https://programmingsimplicity.substack.com/p/repeating-architectural-patterns</link><guid isPermaLink="false">https://programmingsimplicity.substack.com/p/repeating-architectural-patterns</guid><dc:creator><![CDATA[Paul Tarvydas]]></dc:creator><pubDate>Wed, 24 Jun 2026 13:53:55 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!eSyZ!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d69eba9-d5d3-4387-a046-9b881b00bd45_131x131.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>As we build a PBP version that mimics the original <a href="https://www.reddit.com/r/EngineeringPorn/comments/ul49zt/the_original_pong_video_game_had_no_code_and_was/">Atari Pong schematic</a>, I doubt that we will actually see strictly repeating high-level patterns emerge. I think that the strictly repeating patterns are embodied in the ICs used in the original circuit. Combinations of ICs on the schematic are used to create architectural chunks that don&#8217;t repeat verbatim.</p><p>The design of ICs is about as far as we can take the idea of strict, repeatable patterns. The design of the Pong schematic uses low-level repeatable patterns to build up higher-level chunks of architecture.</p><p>PBP is an attempt to allow expressing such chunks in a readable manner. We should be able to reuse low-level parts to build up customizable medium-level parts that are used to build up specific parts for a specific project.</p><p>Seasoned &#8220;architects&#8221; may recognize such high-level patterns and reuse them as customizable ideas that can be used (in a modified way) in other architectures.</p><p>We already see this kind of thing happening in electronics and other fields of engineering, e.g. civil engineering and bridge design - not all bridges are designed the same way, but sometimes general architectural features are reused.</p><p>When I showed the Pong schematic to someone versed in electronics design, they &#8220;immediately&#8221; saw architectural patterns in the design, but with tweaks. For example, a comment was that BCD score was being rasterized for display on a then-standard cathode ray tube (CRT). The person saw that some low-level ICs were used in an idiomatic manner.</p><p>I guess one might say that PBP is a way to build up custom Designs using very low level patterns, while leaving the high-level Design readable. Currently, electronics schematics are filled with implementation details that obfuscate the design to anyone but seasoned architected.</p><p>Likewise with the way we write code. The code consists of a bunch of details that don&#8217;t tend to reveal the over-lying Design, unless the programmer(s) was careful to use common idioms and unless the reader is a seasoned programmer who rapidly recognizes the use of such idioms.</p><p>The colourized version of the Pong schematic was probably done by a seasoned electronics person. The person recognized areas within the circuit that were aimed at solving specific sub-problems, then grouped such areas together by colouring them. People who aren&#8217;t versed in reading schematics can understand the colourized groups without needing to understand the actual details of the electronics inside each group.</p><h2>Resources</h2><h3>Articles</h3><ul><li><p><a href="https://programmingsimplicity.substack.com/p/building-software-using-black-boxes?r=1egdky">Building Software Using Black Boxes</a></p></li><li><p><a href="https://programmingsimplicity.substack.com/p/pbp-black-box-abstraction-port-fan?r=1egdky">PBP Black Box Abstraction, Ports, Fan-out, Fan-in</a></p></li></ul><h3>Videos</h3><ul><li><p><a href="https://youtu.be/EFTzFA82YRc?t=330">how to install PBP</a></p></li><li><p><a href="https://youtu.be/EFTzFA82YRc">Hello World and simple parallelism in PBP</a></p></li><li><p><a href="https://www.youtube.com/playlist?list=PLHh2_dCKBPjY0_tTpPa-bRFMLHY0jc3DV">building a dsl (playlist)</a></p></li><li><p><a href="https://www.youtube.com/playlist?list=PLHh2_dCKBPjbBN2R8xwBiS4nHlo5iQjqS">PBP basics (playlist)</a></p></li><li><p><a href="https://www.youtube.com/playlist?list=PLHh2_dCKBPjbBN2R8xwBiS4nHlo5iQjqS">PBP Cookbook (playlist)</a></p></li><li><p><a href="https://www.youtube.com/playlist?list=PLHh2_dCKBPjYBmubkBfn0LSbDMRKsr9Ui">Towards PBP (playlist)</a></p></li><li><p><a href="https://www.youtube.com/playlist?list=PLHh2_dCKBPjYEGrLE2IJAXp5V8eHBwzu4">SCNs (playlist)</a></p></li></ul><h3>Examples</h3><ul><li><p><a href="https://programmingsimplicity.substack.com/p/pbp-kernel-portability?r=1egdky">PBP Kernel Portability</a></p></li><li><p><a href="https://github.com/guitarvydas/larson">Larson scanner written in PBP</a></p></li><li><p><a href="https://github.com/guitarvydas/pbp-pong/tree/atari">Pong in PBP (very WIP)</a></p></li><li><p><a href="https://github.com/guitarvydas/ordering">Reasoning About Ordering</a></p></li><li><p><a href="https://programmingsimplicity.substack.com/p/2024-06-26-exploring-technique-and">Exploring Techniques and Notations for Augmenting DX (Demo for FoP)</a></p></li><li><p><a href="https://github.com/guitarvydas/ason">ASON sample tokenizer</a></p></li><li><p><a href="https://github.com/guitarvydas/eh">early code repo for &#279; (eh) ancestor of PBP (contains basics for PBP/0D reasoning)</a></p></li><li><p><a href="https://github.com/guitarvydas/thinkingProlog">thinking Prolog: small sample of reasoning in Prolog</a></p></li><li><p><a href="https://github.com/guitarvydas/cl-holm-prolog">Nils Holm&#8217;s Prolog in Scheme code ported to Common Lisp</a></p></li><li><p><a href="https://github.com/guitarvydas/verbatim">sample of creating &#8220;verbatims&#8221; in little language</a><br></p><ul><li><p>verbatims enable staged computation</p></li><li><p>if a pass converts code to final code, it wraps the generated code in a &#8220;verbatim&#8221; and subsequent passes just ignore it and don&#8217;t try to parse it</p></li></ul></li><li><p><a href="https://github.com/guitarvydas/applysyntactic">example of using &#8220;applySyntactic&lt;&#8230;&gt;&#8221; in Ohm</a></p></li><li><p><a href="https://github.com/guitarvydas/20220604md2brace">using OhmJS to convert markdown to structured (bracketed) form</a></p></li><li><p><a href="https://github.com/guitarvydas/behavior_tree_to_cpp">example of converting textual behaviour trees to JSON then to C++</a></p></li><li><p><a href="https://computingsimplicity.neocities.org/blogs/OhmInSmallSteps.pdf">Ohm In Small Steps (diary of converting some Scheme code to Javascript)</a></p></li><li><p><a href="https://research.cs.queensu.ca/home/cordy/pub/downloads/ssl/">PT Pascal and S/SL</a></p></li><li><p><a href="https://guitarvydas.github.io/2020/12/09/CALL-RETURN-Spaghetti.html">Call Return Spaghetti (essay)</a></p></li></ul><h1>See Also</h1><p><em>Email</em>: <a href="mailto:ptcomputingsimplicity@gmail.com">ptcomputingsimplicity@gmail.com</a><br><em>Substack</em>: <a href="http://paultarvydas.substack.com/">paultarvydas.s. bstack.com</a><br><em>Videos</em>: <a href="https://www.youtube.com/@programmingsimplicity2980">https://www. youtube.com/@programmingsimplicity2980</a><br><em>Discord</em>: <a href="https://discord.gg/65YZUh6Jpq">https://discord.gg/65YZUh6J. q</a><br><em>Leanpub</em>: <a href="https://leanpub.com/u/paul-tarvydas">https:. /leanpub.com/u/paul-tarvydas</a><br><em>Twitter</em>: @paul_tarvydas<br><em>Bluesky:</em> @paultarvydas.bsky.social<br><em>Mastodon:</em> @paultarvydas<br><em>(earlier) Blog:</em> <a href="http://guitarvydas.github.io/">guitarvydas.github.io</a><br><em>References:</em> <a href="https://guitarvydas.github.io/2024/01/06/References.html">https://guitarvydas.github.io/2024/01/06/References.html</a></p><p><em>Paid subscriptions are a voluntary way to support this work.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/p/repeating-architectural-patterns/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/p/repeating-architectural-patterns/comments"><span>Leave a comment</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/p/repeating-architectural-patterns?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/p/repeating-architectural-patterns?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/subscribe?"><span>Subscribe now</span></a></p>]]></content:encoded></item><item><title><![CDATA[AI Is No Code]]></title><description><![CDATA[2026-06-24]]></description><link>https://programmingsimplicity.substack.com/p/ai-is-no-code</link><guid isPermaLink="false">https://programmingsimplicity.substack.com/p/ai-is-no-code</guid><dc:creator><![CDATA[Paul Tarvydas]]></dc:creator><pubDate>Wed, 24 Jun 2026 12:37:46 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!eSyZ!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d69eba9-d5d3-4387-a046-9b881b00bd45_131x131.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>AI is No Code for one specific architectural pattern. The one I call &#8220;function-based&#8221;, which is synchronous and sequential.</p><p>You <em>can</em> build other architectural patterns on top of that one architectural pattern, but the substrate function-based pattern restricts your architectural thinking (&#8220;Design&#8221;). For example, you cannot build Forth on top of that substrate. Forth doesn&#8217;t use the function-based &#8220;calling convention&#8221;. The best you can do is to build a fake Forth that adheres to a prematurely-supplied calling convention. Nor, can you build something that is asynchronous and fully parallel on top of that substrate, since the substrate has already eliminated asynchrony from any design you put on top of it. The best you can do is to define synchronous &#8220;reactors&#8221; and then plumb them together by hand in a manner analogous to writing assembler.</p><p>I&#8217;ve built many Designs using a different substrate architectural pattern - asynchronous, electronic IC based. From that experience, I conclude that the function-based pattern is too restrictive and bloatful and that we need to break free of it. AI won&#8217;t help with that.</p><h1>See Also</h1><p><em>Email</em>: <a href="mailto:ptcomputingsimplicity@gmail.com">ptcomputingsimplicity@gmail.com</a><br><em>Substack</em>: <a href="http://paultarvydas.substack.com/">paultarvydas.s. bstack.com</a><br><em>Videos</em>: <a href="https://www.youtube.com/@programmingsimplicity2980">https://www. youtube.com/@programmingsimplicity2980</a><br><em>Discord</em>: <a href="https://discord.gg/65YZUh6Jpq">https://discord.gg/65YZUh6J. q</a><br><em>Leanpub</em>: <a href="https://leanpub.com/u/paul-tarvydas">https:. /leanpub.com/u/paul-tarvydas</a><br><em>Twitter</em>: @paul_tarvydas<br><em>Bluesky:</em> @paultarvydas.bsky.social<br><em>Mastodon:</em> @paultarvydas<br><em>(earlier) Blog:</em> <a href="http://guitarvydas.github.io/">guitarvydas.github.io</a><br><em>References:</em> <a href="https://guitarvydas.github.io/2024/01/06/References.html">https://guitarvydas.github.io/2024/01/06/References.html</a></p><p><em>Paid subscriptions are a voluntary way to support this work.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/p/ai-is-no-code/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/p/ai-is-no-code/comments"><span>Leave a comment</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/p/ai-is-no-code?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/p/ai-is-no-code?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/subscribe?"><span>Subscribe now</span></a></p>]]></content:encoded></item><item><title><![CDATA[Anti Assimilation]]></title><description><![CDATA[2026-06-19]]></description><link>https://programmingsimplicity.substack.com/p/anti-assimilation</link><guid isPermaLink="false">https://programmingsimplicity.substack.com/p/anti-assimilation</guid><dc:creator><![CDATA[Paul Tarvydas]]></dc:creator><pubDate>Fri, 19 Jun 2026 11:39:44 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!eSyZ!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d69eba9-d5d3-4387-a046-9b881b00bd45_131x131.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1>Anti Assimilation</h1><p>2026-06-19</p><p>The way we build software - time-shared and centralized - is no longer appropriate for the problem domains of the 21st century, regardless of how convenient the synchronous, sequential, centralized paradigm seems.</p><p>Any code sitting atop Linux (or other even more bloated operating systems) has a base tax of about 30,000,000 lines of code on top of CPU ICs that use many more transistors than what was needed to build Sketchpad, Visicalc, Turbo Pascal, Unix V1 (UNIX was originally written in assembler, not K&amp;R C), etc. We can do a <em>lot</em> better.</p><p>Continuing to build software the same way over and over again, expecting different results is a death march based on unwillingness to accurately assess the cost of doing so and based on the belief that there is only one purpose for &#8220;computers&#8221; (a better name might be RM - Reprogrammable Machines).</p><p>Pure functional programming - modern Sector Lisp - costs about 354 lines of assembler. Most other programming languages pay a huge tax for stretching and generalizing the functional programming model.</p><p>We need to think outside of the box of the synchronous, sequential, centralized model. Machine code and ICs can support many more kinds of models than just functional programming (K&amp;R C may have been a convenient abstraction, but, subsequently, C has been distorted into a functional programming language (albeit flawed) replete with function-based calling conventions).</p><p>Progress should result in <em>less</em> code. I don&#8217;t believe that this is happening.</p><p>Our current programming model makes us believe that issues - e.g. assignment, synchronous concurrency, asynchronous parallelism, thread safety, control flow - falling outside of the functional, synchronous, sequential model can be ignored or simply assimilated. Yet, <a href="https://guitarvydas.github.io/2023/11/27/Statecharts-Papers-We-Love-Video.html">Harel</a> came up with a better notation for one of those issues some 40 years ago (Statecharts for reactive control flow). I think that we should be using models for programming that allow us to compose solutions using many paradigms, each with laser-focused languages to support them - specialization instead of generalization and the kitchen sink approach. Decentralization instead of centralization and assimilation. Eliminating problems instead of laboriously assimilating solutions to them.</p><p>Switching to a decentralized model could eliminate the issue of thread safety. Simply eliminating thread safety concerns would noticeably reduce the size and complexity of programming languages. Since the main role of operating systems is to act as scaffolding to support the functional model, can something be done about that issue?</p><p>Everything we&#8217;ve accomplished in the past 50 years fits inside just one of the bubbles on my diagram labelled &#8220;app&#8221; in a previous <a href="https://programmingsimplicity.substack.com/p/the-hardware-changed-the-software?r=1egdky">article</a>. We haven&#8217;t really addressed the rest of the stuff, other than by applying notation worship to assimilate each new gotcha, in a whack-a-mole manner, into the ball of stuff that we already have. <a href="https://programmingsimplicity.substack.com/p/capt-grace-hopper-on-future-possibilities?r=1egdky">Grace Hopper</a> warned against this approach.</p><p>Functions and math-like notation (mangled by 500 year-old Gutenberg technology) aren&#8217;t the only way to program the things we call &#8220;computers&#8221;.</p><p>It is entirely reasonable to specialize and drill down onto a thin slice of programming. But, it must be remembered that this is not programming, it is just a thin slice of programming. Looking at all problems through a single lens has a cost.</p><h1>See Also</h1><p><em>Email</em>: <a href="mailto:ptcomputingsimplicity@gmail.com">ptcomputingsimplicity@gmail.com</a><br><em>Substack</em>: <a href="http://paultarvydas.substack.com/">paultarvydas.s. bstack.com</a><br><em>Videos</em>: <a href="https://www.youtube.com/@programmingsimplicity2980">https://www. youtube.com/@programmingsimplicity2980</a><br><em>Discord</em>: <a href="https://discord.gg/65YZUh6Jpq">https://discord.gg/65YZUh6J. q</a><br><em>Leanpub</em>: <a href="https://leanpub.com/u/paul-tarvydas">https:. /leanpub.com/u/paul-tarvydas</a><br><em>Twitter</em>: @paul_tarvydas<br><em>Bluesky:</em> @paultarvydas.bsky.social<br><em>Mastodon:</em> @paultarvydas<br><em>(earlier) Blog:</em> <a href="http://guitarvydas.github.io/">guitarvydas.github.io</a><br><em>References:</em> <a href="https://guitarvydas.github.io/2024/01/06/References.html">https://guitarvydas.github.io/2024/01/06/References.html</a></p><p><em>Paid subscriptions are a voluntary way to support this work.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/p/anti-assimilation/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/p/anti-assimilation/comments"><span>Leave a comment</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/p/anti-assimilation?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/p/anti-assimilation?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/subscribe?"><span>Subscribe now</span></a></p>]]></content:encoded></item><item><title><![CDATA[The Hardware Changed. The Software Didn’t.]]></title><description><![CDATA[CPUs are cheap. Stop pretending they aren&#8217;t. A case for decentralized architecture. 2026-06-13]]></description><link>https://programmingsimplicity.substack.com/p/the-hardware-changed-the-software</link><guid isPermaLink="false">https://programmingsimplicity.substack.com/p/the-hardware-changed-the-software</guid><dc:creator><![CDATA[Paul Tarvydas]]></dc:creator><pubDate>Sun, 14 Jun 2026 19:32:57 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!yM3G!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c0de6ae-b8c3-43d3-a143-f3e146fbbd5b_3153x1383.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>TL;DR</h2><p>The centralized CPU model is a historical accident driven by 1950s economics. CPUs and memory were expensive, so we time-shared a single machine and faked parallelism. Hardware has since gotten cheap. We should stop architecting software as if it hasn&#8217;t.</p><h2>L;R</h2><h3>The centralized model is an artifact of scarcity</h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!yM3G!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c0de6ae-b8c3-43d3-a143-f3e146fbbd5b_3153x1383.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!yM3G!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c0de6ae-b8c3-43d3-a143-f3e146fbbd5b_3153x1383.png 424w, https://substackcdn.com/image/fetch/$s_!yM3G!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c0de6ae-b8c3-43d3-a143-f3e146fbbd5b_3153x1383.png 848w, https://substackcdn.com/image/fetch/$s_!yM3G!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c0de6ae-b8c3-43d3-a143-f3e146fbbd5b_3153x1383.png 1272w, https://substackcdn.com/image/fetch/$s_!yM3G!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c0de6ae-b8c3-43d3-a143-f3e146fbbd5b_3153x1383.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!yM3G!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c0de6ae-b8c3-43d3-a143-f3e146fbbd5b_3153x1383.png" width="1456" height="639" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0c0de6ae-b8c3-43d3-a143-f3e146fbbd5b_3153x1383.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:639,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!yM3G!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c0de6ae-b8c3-43d3-a143-f3e146fbbd5b_3153x1383.png 424w, https://substackcdn.com/image/fetch/$s_!yM3G!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c0de6ae-b8c3-43d3-a143-f3e146fbbd5b_3153x1383.png 848w, https://substackcdn.com/image/fetch/$s_!yM3G!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c0de6ae-b8c3-43d3-a143-f3e146fbbd5b_3153x1383.png 1272w, https://substackcdn.com/image/fetch/$s_!yM3G!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c0de6ae-b8c3-43d3-a143-f3e146fbbd5b_3153x1383.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Early computers were extraordinarily expensive. CPUs and memory cost fortunes. This economic reality drove a specific architectural choice: one central processor, shared by many processes, switching between them fast enough to create the illusion of simultaneous execution. That illusion is what we call multitasking.</p><p>The illusion has a cost. Processes sharing memory introduce race conditions. Race conditions require thread safety. Thread safety requires locks. Locks introduce deadlocks. Deadlocks require careful engineering. That careful engineering leaks into every layer of the stack &#8212; operating systems, runtimes, frameworks, application code.</p><p>This is not a law of nature. It is a tax on a design decision made when hardware was scarce.</p><h3>The mismatch that nobody names</h3><p>The shared-memory model does not extend to distributed systems. The internet is not a shared-memory machine. Nodes are physically distant. Network latency is measured in milliseconds, not nanoseconds. Packets are dropped. Clocks drift. Nothing is synchronized by default.</p><p>We have spent decades building increasingly complicated machinery to paper over this mismatch &#8212; cache coherency protocols, multi-core synchronization hardware, distributed consensus algorithms, eventual consistency models. Each layer of complexity is a response to the fundamental mismatch between a shared-memory mental model and a physically asynchronous reality.</p><p>The hardware knows the truth. CPUs run in parallel. Network nodes run in parallel. The hardware is asynchronous by default. The software pretends otherwise.</p><h3>Thread safety has poisoned language design</h3><p>Thread safety is not a property of programs. It is a property of the shared-memory model. Remove shared memory and thread safety ceases to exist as a concept. It does not need to be solved. It needs to be made irrelevant.</p><p>This distinction has been lost. A generation of language designers treated thread safety as a fundamental problem of computation and built it into the core of their languages. Mutexes, semaphores, atomic operations, memory barriers, volatile qualifiers, synchronized blocks &#8212; these are not features. They are patches on an architecture that should not have required them.</p><p>The damage runs deeper than syntax. Languages now ship with concurrency primitives as first-class citizens. Programmers learn these primitives early and internalize them as part of what programming is. The question is no longer &#8220;why does this need a lock?&#8221; The question is &#8220;which kind of lock should I use here?&#8221; The accidental complexity has been promoted to essential complexity. It appears in textbooks. It appears in job interviews. It appears in the checklist of skills a senior engineer is expected to possess.</p><p>Most working programmers today have never written production software that does not grapple with thread safety in some form. To them it is simply part of the job &#8212; as natural and unavoidable as parsing or memory allocation. The idea that the entire concern could be eliminated by a different architecture is not on the table. It is not even a thought that occurs to ask.</p><p>This is how accidental complexity becomes permanent. Not by conspiracy, but by familiarity. Each generation of programmers learns the workarounds, masters them, teaches them to the next generation, and the underlying architectural mistake recedes further from view.</p><h3>The decentralized model follows the hardware</h3><p>CPUs and memory are now cheap. The economic constraint that justified the centralized model has evaporated.</p><p>The decentralized model takes the hardware at face value. Each node has its own CPU and private memory. Nodes do not share memory. Nodes communicate by passing messages. This is not a simulation of parallelism &#8212; it is actual parallelism.</p><h4>Smart Apps</h4><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Ivsw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb631dc8c-659a-4326-8b77-854d0e90d4cc_1653x693.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Ivsw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb631dc8c-659a-4326-8b77-854d0e90d4cc_1653x693.png 424w, https://substackcdn.com/image/fetch/$s_!Ivsw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb631dc8c-659a-4326-8b77-854d0e90d4cc_1653x693.png 848w, https://substackcdn.com/image/fetch/$s_!Ivsw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb631dc8c-659a-4326-8b77-854d0e90d4cc_1653x693.png 1272w, https://substackcdn.com/image/fetch/$s_!Ivsw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb631dc8c-659a-4326-8b77-854d0e90d4cc_1653x693.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Ivsw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb631dc8c-659a-4326-8b77-854d0e90d4cc_1653x693.png" width="1456" height="610" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b631dc8c-659a-4326-8b77-854d0e90d4cc_1653x693.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:610,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Ivsw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb631dc8c-659a-4326-8b77-854d0e90d4cc_1653x693.png 424w, https://substackcdn.com/image/fetch/$s_!Ivsw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb631dc8c-659a-4326-8b77-854d0e90d4cc_1653x693.png 848w, https://substackcdn.com/image/fetch/$s_!Ivsw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb631dc8c-659a-4326-8b77-854d0e90d4cc_1653x693.png 1272w, https://substackcdn.com/image/fetch/$s_!Ivsw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb631dc8c-659a-4326-8b77-854d0e90d4cc_1653x693.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h4>Smart Devices</h4><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Hc7E!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c01057-0003-498e-8b58-525dc8b93397_1653x840.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Hc7E!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c01057-0003-498e-8b58-525dc8b93397_1653x840.png 424w, https://substackcdn.com/image/fetch/$s_!Hc7E!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c01057-0003-498e-8b58-525dc8b93397_1653x840.png 848w, https://substackcdn.com/image/fetch/$s_!Hc7E!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c01057-0003-498e-8b58-525dc8b93397_1653x840.png 1272w, https://substackcdn.com/image/fetch/$s_!Hc7E!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c01057-0003-498e-8b58-525dc8b93397_1653x840.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Hc7E!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c01057-0003-498e-8b58-525dc8b93397_1653x840.png" width="1456" height="740" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e2c01057-0003-498e-8b58-525dc8b93397_1653x840.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:740,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Hc7E!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c01057-0003-498e-8b58-525dc8b93397_1653x840.png 424w, https://substackcdn.com/image/fetch/$s_!Hc7E!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c01057-0003-498e-8b58-525dc8b93397_1653x840.png 848w, https://substackcdn.com/image/fetch/$s_!Hc7E!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c01057-0003-498e-8b58-525dc8b93397_1653x840.png 1272w, https://substackcdn.com/image/fetch/$s_!Hc7E!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c01057-0003-498e-8b58-525dc8b93397_1653x840.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h4>Decentralized Model</h4><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4-jb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2ff20ae-dbeb-4882-97ac-d0df21b55cc2_1368x663.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4-jb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2ff20ae-dbeb-4882-97ac-d0df21b55cc2_1368x663.png 424w, https://substackcdn.com/image/fetch/$s_!4-jb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2ff20ae-dbeb-4882-97ac-d0df21b55cc2_1368x663.png 848w, https://substackcdn.com/image/fetch/$s_!4-jb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2ff20ae-dbeb-4882-97ac-d0df21b55cc2_1368x663.png 1272w, https://substackcdn.com/image/fetch/$s_!4-jb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2ff20ae-dbeb-4882-97ac-d0df21b55cc2_1368x663.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4-jb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2ff20ae-dbeb-4882-97ac-d0df21b55cc2_1368x663.png" width="1368" height="663" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b2ff20ae-dbeb-4882-97ac-d0df21b55cc2_1368x663.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:663,&quot;width&quot;:1368,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!4-jb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2ff20ae-dbeb-4882-97ac-d0df21b55cc2_1368x663.png 424w, https://substackcdn.com/image/fetch/$s_!4-jb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2ff20ae-dbeb-4882-97ac-d0df21b55cc2_1368x663.png 848w, https://substackcdn.com/image/fetch/$s_!4-jb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2ff20ae-dbeb-4882-97ac-d0df21b55cc2_1368x663.png 1272w, https://substackcdn.com/image/fetch/$s_!4-jb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2ff20ae-dbeb-4882-97ac-d0df21b55cc2_1368x663.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h4>Consequences</h4><p>The consequences are significant. Thread safety disappears as a concern. There is nothing to share. The operating system&#8217;s job of mediating access to shared resources shrinks, or vanishes entirely. Applications own their CPU. They are not slowed by context-switching or contention.</p><h4>This Has Been Done Before</h4><p>Apple demonstrated this in hardware decades ago. The LaserWriter was a smart printer. It ran PostScript on its own CPU with its own memory. The Macintosh sent it a document; the printer handled the rest. The HP model of the same era exposed raw printer hardware to the host CPU &#8212; the host had to manage the device. Apple&#8217;s model was right. The device is smart. The wire carries messages.</p><h3>Structured messaging is the discipline that makes it scale</h3><p>Early message-passing systems failed. The reason is not that message passing is wrong. The reason is that unstructured message passing does not scale.</p><p>The solution is hierarchy. Messages flow as requests down the tree and summaries flow back up. No node communicates directly with its peers. A node sends requests to its direct subordinates and receives results from them. Peer-to-peer communication is handled entirely by a common parent node &#8212; there is no going over the boss&#8217;s head, and no reaching two levels down to micromanage a subordinate&#8217;s subordinates.</p><p>This is not a novel idea. It is how every functional organization has operated for centuries. Large businesses stay coherent by enforcing exactly this discipline. The org chart is not bureaucratic overhead. It is a scaling solution. The same discipline that keeps a ten-thousand-person company from collapsing into chaos is what keeps a distributed software system from collapsing into an undebuggable message storm.</p><p>A node knows only its direct children. It does not know what those children do internally. It does not reach past them to micromanage their subordinates. This is topology-blindness applied to network architecture.</p><h4>Request Flow</h4><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!r9iV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77de5509-b366-408a-983f-affff714ae67_1863x693.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!r9iV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77de5509-b366-408a-983f-affff714ae67_1863x693.png 424w, https://substackcdn.com/image/fetch/$s_!r9iV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77de5509-b366-408a-983f-affff714ae67_1863x693.png 848w, https://substackcdn.com/image/fetch/$s_!r9iV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77de5509-b366-408a-983f-affff714ae67_1863x693.png 1272w, https://substackcdn.com/image/fetch/$s_!r9iV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77de5509-b366-408a-983f-affff714ae67_1863x693.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!r9iV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77de5509-b366-408a-983f-affff714ae67_1863x693.png" width="1456" height="542" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/77de5509-b366-408a-983f-affff714ae67_1863x693.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:542,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!r9iV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77de5509-b366-408a-983f-affff714ae67_1863x693.png 424w, https://substackcdn.com/image/fetch/$s_!r9iV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77de5509-b366-408a-983f-affff714ae67_1863x693.png 848w, https://substackcdn.com/image/fetch/$s_!r9iV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77de5509-b366-408a-983f-affff714ae67_1863x693.png 1272w, https://substackcdn.com/image/fetch/$s_!r9iV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77de5509-b366-408a-983f-affff714ae67_1863x693.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h4>Summary Flow</h4><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ZvXS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d2892c9-4677-426f-8db6-d24d10630405_1863x693.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ZvXS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d2892c9-4677-426f-8db6-d24d10630405_1863x693.png 424w, https://substackcdn.com/image/fetch/$s_!ZvXS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d2892c9-4677-426f-8db6-d24d10630405_1863x693.png 848w, https://substackcdn.com/image/fetch/$s_!ZvXS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d2892c9-4677-426f-8db6-d24d10630405_1863x693.png 1272w, https://substackcdn.com/image/fetch/$s_!ZvXS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d2892c9-4677-426f-8db6-d24d10630405_1863x693.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ZvXS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d2892c9-4677-426f-8db6-d24d10630405_1863x693.png" width="1456" height="542" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3d2892c9-4677-426f-8db6-d24d10630405_1863x693.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:542,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ZvXS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d2892c9-4677-426f-8db6-d24d10630405_1863x693.png 424w, https://substackcdn.com/image/fetch/$s_!ZvXS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d2892c9-4677-426f-8db6-d24d10630405_1863x693.png 848w, https://substackcdn.com/image/fetch/$s_!ZvXS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d2892c9-4677-426f-8db6-d24d10630405_1863x693.png 1272w, https://substackcdn.com/image/fetch/$s_!ZvXS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d2892c9-4677-426f-8db6-d24d10630405_1863x693.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>The development environment needs to change too</h3><p>One honest complication: software development happens on single machines. A developer writing a decentralized application is still sitting in front of one CPU with shared memory.</p><p>Right now, we handle this backwards. We build systems that fake asynchronous processing as if it were synchronous &#8212; we write code that calls remote services as if they were simple function calls that pause, wait for a result, and always return &#8212; as if the network were just a slow piece of memory &#8212; then we hide the asynchrony and spend enormous effort managing the consequences when the illusion breaks. Then we ship the entire development environment to users. Users must buy computers running operating systems that support faked multi-processing. The bloat, the context-switching overhead, the complicated scheduling algorithms &#8212; all of it lands on the user&#8217;s machine because we never separated the development model from the deployment target.</p><p>We need to invert this. Development systems should fake asynchronous message-passing on a single machine, not fake synchrony on top of an asynchronous reality. Each component should be treated as if it owns a private CPU and private memory. Components communicate only by passing messages. No shared memory. No thread safety. The fact that the underlying machine is actually running these components by time-sharing a single CPU is an implementation detail of the development environment &#8212; not an architectural assumption that bleeds into the design.</p><p>One might expect that faking message-passing on a single development machine would make apps noticeably slower. This is not obviously true. Avoiding shared memory by default does impose a cost on apps that genuinely benefit from bulk data transfers &#8212; but it does not tax the vast majority of apps that never needed that optimization in the first place. The current version of PBP builds this fake asynchronous processing from scratch, in a green-thread manner. This implies &#8212; though it has not yet been fully tested &#8212; that PBP does not actually require an operating system as we know it. If that holds, the target hardware does not need to be burdened with a bloated OS, nor with the costs of time-sharing, context-switching, and the overhead of complicated scheduling algorithms. We should be able to ship simpler, leaner systems to users. Not copies of our development environments.</p><p>Our current workflow makes this worse in a specific way. We write single synchronous nodes first, then retrofit reactivity onto them so they can be plumbed together &#8212; callbacks, event emitters, promise chains, async/await. This is programming asynchrony in assembler. We are manually encoding, at the application level, coordination that should be handled in a higher level, asynchronous architectural manner. The result is code that is hard to read, hard to reason about, and hard to compose.</p><p>That said, the existing body of synchronous software is not worthless. Code written for a single synchronous node can be wrapped and treated as a leaf component in a larger asynchronous scheme. The wrapper handles the message boundary. The interior of the component stays exactly as it was. This gives us a migration path. We do not need to discard what works. We need to stop using it as the architectural model for the whole system.</p><h3>The model is not hypothetical</h3><p>Electrical engineers have run this architecture for as long as there have been chips. VHDL synthesis describes hardware components with private state communicating through ports. Schematics are topology diagrams, not shared-memory diagrams. EEs do not worry about thread safety. Their components run in parallel because the hardware runs in parallel.</p><p>Software inherited the centralized model from economic necessity. The necessity is gone. The model should follow.</p><h2>See Also</h2><p><em>Email</em>: <a href="mailto:ptcomputingsimplicity@gmail.com">ptcomputingsimplicity@gmail.com</a><br><em>Substack</em>: <a href="http://paultarvydas.substack.com/">paultarvydas.s. bstack.com</a><br><em>Videos</em>: <a href="https://www.youtube.com/@programmingsimplicity2980">https://www. youtube.com/@programmingsimplicity2980</a><br><em>Discord</em>: <a href="https://discord.gg/65YZUh6Jpq">https://discord.gg/65YZUh6J. q</a><br><em>Leanpub</em>: <a href="https://leanpub.com/u/paul-tarvydas">https:. /leanpub.com/u/paul-tarvydas</a><br><em>Twitter</em>: @paul_tarvydas<br><em>Bluesky:</em> @paultarvydas.bsky.social<br><em>Mastodon:</em> @paultarvydas<br><em>(earlier) Blog:</em> <a href="http://guitarvydas.github.io/">guitarvydas.github.io</a><br><em>References:</em> <a href="https://guitarvydas.github.io/2024/01/06/References.html">https://guitarvydas.github.io/2024/01/06/References.html</a></p><p><em>Paid subscriptions are a voluntary way to support this work.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/p/the-hardware-changed-the-software/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/p/the-hardware-changed-the-software/comments"><span>Leave a comment</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/p/the-hardware-changed-the-software?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/p/the-hardware-changed-the-software?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/subscribe?"><span>Subscribe now</span></a></p>]]></content:encoded></item><item><title><![CDATA[Software Development Has a Brainstorming Problem]]></title><description><![CDATA[And what Failure Driven Development might do about it 2026-06-06]]></description><link>https://programmingsimplicity.substack.com/p/software-development-has-a-brainstorming</link><guid isPermaLink="false">https://programmingsimplicity.substack.com/p/software-development-has-a-brainstorming</guid><dc:creator><![CDATA[Paul Tarvydas]]></dc:creator><pubDate>Sun, 07 Jun 2026 02:44:14 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!eSyZ!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d69eba9-d5d3-4387-a046-9b881b00bd45_131x131.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Every serious creative field has developed a rich pedagogy around brainstorming &#8212; the generative phase of work where raw material is produced before the evaluating mind gets involved. Songwriting has Pat Pattison. Fiction writing has Natalie Goldberg and Julia Cameron. Software development has&#8230; sprint planning?</p><p>This gap is real, and it matters. Here&#8217;s a tour of what the other fields figured out, why software missed it, and why Failure Driven Development might be the framework that finally closes the gap.</p><div><hr></div><h2>TL;DR</h2><p>The songwriting and writing teachers all share one core move: make it safe to produce bad output. Software culture has never institutionalized this. FDD reframes failure as the mechanism of discovery &#8212; which is exactly the philosophical infrastructure the generative phase of programming has been missing.</p><h2>L;R</h2><h3>What Songwriting Teachers Figured Out</h3><p>Pat Pattison, the Berklee College of Music professor whose students include John Mayer and Gillian Welch, built his brainstorming pedagogy around a technique he calls <strong>object writing</strong>. The exercise is simple: pick an object &#8212; any person, place, or thing &#8212; set a timer for ten minutes, and write about it using all seven senses. The five familiar ones plus <em>organic sense</em> (how your body feels internally &#8212; butterflies in your stomach) and <em>kinesthetic sense</em> (how your body moves in relation to space &#8212; the room was spinning). The rule is no self-editing, no crossing out, and stopping when the timer goes off regardless of where you are.</p><p>The deeper principle is what Pattison calls &#8220;the art of diving.&#8221; In daily life we skim the surface of experience. Object writing forces a descent into concrete sensory detail &#8212; the kind of specific, embodied language that listeners can actually share. Abstract emotion becomes communicable only when grounded in sensory particulars.</p><p>He also teaches the title as a brainstorming scaffold: a strong title carries implicit &#8220;DNA&#8221; &#8212; a set of concepts and promises &#8212; that organizes what the verses can explore. And during the generative phase, the rule is an explicit &#8220;no free zone&#8221;: the inner critic is told to stand down entirely.</p><p>Other songwriting teachers work adjacent territory. Jason Blume mines everyday conversation and overheard phrases for title ideas. Ralph Murphy (ASCAP) starts with the title and asks what promise it makes to the listener, then brainstorms only what fulfills that promise. Jimmy Webb (<em>Tunesmith</em>) is more romantic about it &#8212; walks, drives, solitude, boredom &#8212; creating conditions for the unconscious to work rather than following a system. Sheila Davis (<em>The Songwriter&#8217;s Idea Book</em>) is the most toolkit-heavy: forty distinct strategies including clustering, mind-mapping, &#8220;what if&#8221; scenarios, and working from photographs.</p><p>The consensus across all of them: write before you edit, collect more than you need, and anchor abstract emotion in concrete specific detail.</p><h3>What Writing Teachers Figured Out</h3><p>The fiction and nonfiction world arrived at essentially the same pedagogy independently.</p><p>Natalie Goldberg (<em>Writing Down the Bones</em>) is the closest to Pattison in spirit: timed &#8220;writing practice,&#8221; keep your hand moving, don&#8217;t cross out, go for the jugular. Very Zen-influenced &#8212; she treats writing practice as a form of meditation.</p><p>Julia Cameron (<em>The Artist&#8217;s Way</em>) prescribes Morning Pages: three longhand pages every morning, stream of consciousness, no re-reading. The explicit goal is not good writing but drainage &#8212; clearing the &#8220;brain sludge&#8221; so the real creative work can flow later.</p><p>Peter Elbow (<em>Writing Without Teachers</em>) coined &#8220;freewriting&#8221; as a formal technique and articulated perhaps the clearest theoretical framing: the <em>generating self</em> and the <em>evaluating self</em> cannot operate simultaneously. They must be sequenced, not interleaved.</p><p>Anne Lamott (<em>Bird by Bird</em>) gives permission with her concept of the &#8220;shitty first draft&#8221; &#8212; the psychological license to write badly is the whole game. Also teaches radical scope narrowing: don&#8217;t write a book, write what you can see through a one-inch picture frame.</p><p>Dorothea Brande (<em>Becoming a Writer</em>, 1934) is arguably the original: write immediately upon waking before the rational mind engages. She predates Cameron by fifty years with essentially the same insight.</p><h3>Why Software Missed This</h3><p>The dominant culture treats programming as engineering or mathematics &#8212; fields where rigor and correctness are the virtues, not generative looseness. The inner critic is baked into the tools: the compiler rejects your shitty first draft immediately. It&#8217;s structurally difficult to maintain &#8220;keep your hand moving, don&#8217;t cross out&#8221; when the environment is constantly evaluating you.</p><p>The field also conflates <em>design</em> brainstorming with <em>implementation</em>. Whiteboard sessions, user stories, sprint planning &#8212; these exist, but they&#8217;re about requirements and architecture, not about the kind of raw generative thinking Pattison or Goldberg are after.</p><p>What does exist in software: sketching and paper prototyping in UX (borrowed from design thinking), &#8220;spike&#8221; solutions as throwaway exploratory code, rubber duck debugging as dialogic thinking-aloud, Ward Cunningham&#8217;s CRC cards for object brainstorming. These are useful but ad hoc &#8212; nobody has assembled them into a coherent pedagogy.</p><p>What&#8217;s entirely missing: a daily timed practice for generating design ideas, uncoupled from correctness. Nobody teaches programmers to separate the generating self from the evaluating self the way Elbow does explicitly. Nobody has articulated the software equivalent of object writing.</p><h3>Where FDD Comes In</h3><p>Failure Driven Development reframes failure as information rather than catastrophe. That is exactly the philosophical move the other fields make to enable generative work &#8212; they just make it at the psychological level rather than the architectural one.</p><p>Lamott&#8217;s shitty first drafts, Pattison&#8217;s no-self-editing rule, Cameron&#8217;s prohibition on re-reading morning pages &#8212; all of these are systems for making failure safe enough to be productive. FDD says the same thing at a deeper level: failure is not a deviation from the process, it&#8217;s the mechanism of the process.</p><p>The songwriting and writing teachers have practice without theory &#8212; they know the techniques work but haven&#8217;t fully articulated why. FDD is positioned to supply the theoretical grounding: the connection between psychological safety-to-fail and actual generative productivity is implicit in Goldberg and Pattison but never made explicit.</p><p>FDD could be the first framework in software that:</p><ul><li><p>Names the generating/evaluating split explicitly in a programming context</p></li><li><p>Provides a concrete practice (analogous to object writing or morning pages) for the generative phase</p></li><li><p>Grounds it in a coherent epistemology rather than just craft wisdom</p></li><li><p>Distinguishes tactical failure-tolerance (agile&#8217;s &#8220;iterate fast&#8221;) from epistemic failure-embrace (&#8220;failure is how you find out what you need to know&#8221;)</p></li></ul><p>That last distinction is the one that makes FDD genuinely new rather than just a restatement of agile. Agile tolerates failure as an unfortunate cost of moving quickly. FDD treats failure as the primary signal &#8212; the thing that tells you where the real problem lives.</p><div><hr></div><p><em>Paul Tarvydas is the originator of Parts-Based Programming (PBP) and Zero Dependency (0D) component architecture. His book</em> Failure Driven Development <em>is available in progress on Leanpub at <a href="https://leanpub.com/failuredrivendevelopment">leanpub.com/failuredrivendevelopment</a>. He writes at <a href="https://programmingsimplicity.substack.com/">Programming Simplicity</a> on Substack.</em></p><div><hr></div><div><hr></div><h1>Appendix: Full Conversation</h1><p><em>The following is the unedited conversation with Claude that generated the ideas in this article.</em></p><div><hr></div><p><strong>Paul:</strong> how does pat pattison teach brainstorming for songwriters</p><p><strong>Claude:</strong> Pattison&#8217;s core brainstorming method is called <strong>object writing</strong>, and it&#8217;s the centerpiece of his book <em>Writing Better Lyrics</em> (1995). Here&#8217;s how it works:</p><p><strong>The basic exercise</strong></p><p>Pick a tangible object &#8212; a person, place, or thing &#8212; and do a timed free-write about it, keeping the writing anchored to all seven senses. Set a timer for 10 minutes, write whatever sensory impressions come to mind in a stream-of-consciousness style, and stop when the timer goes off. Don&#8217;t write in complete sentences, and above all don&#8217;t self-edit. If your mind veers off in different directions, go with it &#8212; as long as it stays sense-bound.</p><p><strong>The seven senses</strong></p><p>The five familiar senses (sight, sound, smell, taste, touch) plus two less obvious ones: organic sense (how your body feels internally &#8212; &#8220;butterflies in your stomach&#8221;) and kinesthetic sense (how your body moves in or relates to space &#8212; &#8220;the room was spinning&#8221;).</p><p><strong>Why sense-bound writing specifically</strong></p><p>In daily life we mostly stay at surface level. In object writing, your job is &#8220;to master the art of diving&#8221; &#8212; getting to the bottom of the sea, finding the shell, opening it, and finding the pearl inside. The idea is that abstract emotions become communicable only when grounded in concrete sensory experience that listeners can share.</p><p><strong>The daily practice angle</strong></p><p>Pattison advises setting your alarm 10 minutes earlier and doing object writing first thing in the morning. He warns against going over 10 minutes &#8212; if you use a longer session one day, you&#8217;ll use it as an excuse to skip the next day.</p><p><strong>The title as brainstorming tool</strong></p><p>Separate from object writing, Pattison also teaches using a title or hook as a brainstorming scaffold &#8212; it immediately suggests implicit concepts (the &#8220;DNA&#8221; of the title), and helps organize ideas into effective sections, making the process efficient while giving structure to what the verses can explore.</p><p><strong>The &#8220;no free zone&#8221; for generating raw material</strong></p><p>In his co-writing and classroom work, Pattison emphasizes a &#8220;NO-free zone&#8221; during the generative phase &#8212; no criticism, no shooting down ideas. The inner critic is explicitly told to stand down while material is being produced.</p><p>In short, his brainstorming philosophy is: bypass the conscious, judgmental mind by flooding the page with sense-specific concrete detail on a tight timer, then mine that raw material for lyric ideas.</p><div><hr></div><p><strong>Paul:</strong> how does jai joseph teach this</p><p><strong>Claude:</strong> I&#8217;m not finding good results specifically on Jai Joseph/Josefs teaching brainstorming as a distinct topic &#8212; his book <em>Writing Music for Hit Songs</em> is focused primarily on melody, harmony, and musical craft rather than the lyric-brainstorming angle that Pattison emphasizes.</p><p>It&#8217;s possible you&#8217;re thinking of a different teacher, or perhaps a specific course or video where Josefs addresses idea generation. Could you give me a bit more context &#8212; is this from a book, a course, a YouTube video, or something else? That would help me find the right person and material.</p><div><hr></div><p><strong>Paul:</strong> any songwriting guru</p><p><strong>Claude:</strong> Here are some of the major songwriting teachers and how they approach brainstorming/idea generation:</p><p><strong>Pat Pattison</strong> (Berklee) &#8212; object writing, as covered above. Sense-bound timed free-writing to bypass the conscious mind.</p><p><strong>Jason Blume</strong> &#8212; teaches a &#8220;title first&#8221; approach. Mine everyday conversation, overheard phrases, and clich&#233;s with a twist for title ideas. Keep a running list at all times; ideas are everywhere.</p><p><strong>John Braheny</strong> (<em>The Craft and Business of Songwriting</em>) &#8212; emphasizes keeping an &#8220;idea file&#8221; &#8212; scraps of paper, recordings, journal entries &#8212; and revisiting them regularly. Raw material accumulates; you mine it later.</p><p><strong>Ralph Murphy</strong> (ASCAP) &#8212; very Nashville-practical: start with the title, ask &#8220;what does this title promise the listener?&#8221; and brainstorm only what fulfills that promise. Ruthlessly cuts anything that doesn&#8217;t serve the title&#8217;s implied contract.</p><p><strong>Jimmy Webb</strong> (<em>Tunesmith</em>) &#8212; more organic and romantic about it: walks, drives, daydreaming, letting the unconscious work. Less systematic than Pattison, more about creating conditions for inspiration &#8212; solitude, boredom, sensory experience.</p><p><strong>Sheila Davis</strong> (<em>The Songwriter&#8217;s Idea Book</em>) &#8212; the most explicitly brainstorm-focused of the lot. Forty distinct strategies including free association, clustering/mind-mapping around a central word, &#8220;what if&#8221; scenarios, and working from images or photographs.</p><p><strong>Berkeley&#8217;s Andrea Stolpe</strong> &#8212; teaches brainstorming from personal story: interview yourself about a specific emotional memory, extract concrete details, then find the universal in the specific.</p><p>The broad consensus across all of them: write before you edit, collect more than you need, and anchor abstract emotion in concrete specific detail. Pattison is the most systematic about the sensory-grounding piece; Davis is the most varied in her toolkit.</p><p>Is there a particular angle you&#8217;re developing this for &#8212; lyrics, melody, or the general creative process?</p><div><hr></div><p><strong>Paul:</strong> how about bookwriting?</p><p><strong>Claude:</strong> Same basic territory &#8212; bypass the inner critic, generate raw material, organize later. Here are the main teachers:</p><p><strong>Natalie Goldberg</strong> (<em>Writing Down the Bones</em>) &#8212; closest to Pattison in spirit. Timed &#8220;writing practice&#8221;: pick a prompt, keep your hand moving, don&#8217;t cross out, go for the jugular. The hand bypasses the censoring mind. Very Zen-influenced; she studied with a Zen teacher and treats writing practice like meditation.</p><p><strong>Julia Cameron</strong> (<em>The Artist&#8217;s Way</em>) &#8212; Morning Pages: three longhand pages every morning, stream of consciousness, no re-reading. Not meant to be good writing &#8212; meant to drain the &#8220;brain sludge&#8221; so the real creative work can flow. Hugely influential across all creative fields.</p><p><strong>Peter Elbow</strong> (<em>Writing Without Teachers</em>) &#8212; coined &#8220;freewriting&#8221; as a formal technique. Timed, uncensored, no stopping. Also teaches &#8220;cooking&#8221; &#8212; letting ideas sit and ferment before shaping them. Distinguishes the generating self from the editing self and insists they can&#8217;t operate simultaneously.</p><p><strong>Anne Lamott</strong> (<em>Bird by Bird</em>) &#8212; &#8220;shitty first drafts.&#8221; Permission to write badly is the whole game. Also teaches extreme narrowing of focus: don&#8217;t write a book, write what you can see through a one-inch picture frame.</p><p><strong>Stephen King</strong> (<em>On Writing</em>) &#8212; situational rather than plot-driven brainstorming. Put characters in a situation and watch what happens; don&#8217;t outline, just discover. Keeps a notebook but trusts his subconscious more than any system.</p><p><strong>Dorothea Brande</strong> (<em>Becoming a Writer</em>, 1934) &#8212; arguably the original. Write immediately upon waking before the rational mind engages. Predates Cameron by fifty years with essentially the same insight.</p><p>The through-line across all of them is identical to the songwriting teachers: separate generation from evaluation, use time pressure or physical momentum to outrun the critic, and treat the first draft as raw material not finished product. Goldberg and Pattison are almost the same pedagogy applied to different crafts.</p><div><hr></div><p><strong>Paul:</strong> my sense is that brainstorming in software development is far less developed than in other fields</p><p><strong>Claude:</strong> That&#8217;s a sharp observation, and I think you&#8217;re right. A few thoughts on why:</p><p><strong>Why software brainstorming is underdeveloped</strong></p><p>The dominant culture treats programming as engineering or mathematics &#8212; fields where rigor and correctness are the virtues, not generative looseness. The inner critic is baked into the tools: the compiler rejects your shitty first draft immediately. It&#8217;s hard to maintain &#8220;keep the hand moving, don&#8217;t cross out&#8221; when the environment is constantly evaluating you.</p><p>Also, the field conflates <em>design</em> brainstorming with <em>implementation</em>. Whiteboard sessions, user stories, sprint planning &#8212; these exist, but they&#8217;re mostly about requirements and architecture, not about the kind of raw generative thinking Pattison or Goldberg are after.</p><p><strong>What does exist</strong></p><ul><li><p>Sketching / paper prototyping in UX/design (borrowed from design thinking)</p></li><li><p>&#8220;Spike&#8221; solutions &#8212; throwaway code to explore a problem space</p></li><li><p>Rubber duck debugging as a kind of dialogic thinking-aloud</p></li><li><p>Ward Cunningham&#8217;s CRC cards for object brainstorming</p></li><li><p>Some of the agile literature touches on it obliquely</p></li></ul><p><strong>What&#8217;s missing</strong></p><p>Nobody in software has articulated the equivalent of &#8220;object writing&#8221; &#8212; a daily timed practice for generating design ideas, uncoupled from correctness. Nobody teaches programmers to separate the generative self from the evaluating self the way Pattison or Elbow do explicitly.</p><p>Your own work on 0D and PBP is arguably closer to this territory than most &#8212; treating diagrams and notations as a way to think <em>before</em> committing to implementation. DaS as a brainstorming medium, essentially.</p><p>Do you think the missing piece is a <em>practice</em> (like morning pages for coders) or a <em>notation</em>that&#8217;s loose enough to support generative thinking without triggering the evaluating mind?</p><div><hr></div><p><strong>Paul:</strong> how about failure driven development (my leanpub book, unfinished)</p><p><strong>Claude:</strong> Your FDD concept is directly relevant here, and potentially a significant contribution to this gap.</p><p><strong>How FDD fits the brainstorming problem</strong></p><p>The songwriting and writing teachers all share a core move: make it safe to produce bad output. Lamott&#8217;s &#8220;shitty first drafts,&#8221; Pattison&#8217;s timed writing with no self-editing, Cameron&#8217;s morning pages you&#8217;re not allowed to re-read. The psychological infrastructure is &#8220;failure is not just acceptable, it&#8217;s the mechanism.&#8221;</p><p>FDD says essentially the same thing at the architectural level &#8212; failure is information, not catastrophe. That&#8217;s the generative insight the software field is missing. Most programmers treat a failing test or a wrong design as something to be minimized and hidden; FDD reframes it as the driver.</p><p><strong>What FDD could add that the others don&#8217;t have</strong></p><p>The songwriting teachers have practice but no theory of <em>why</em> failure-tolerance works cognitively. You&#8217;re positioned to supply that &#8212; the connection between psychological safety-to-fail and actual generative productivity is implicit in Goldberg and Pattison but never made explicit.</p><p>FDD could be the first framework that:</p><ul><li><p>Names the generative/evaluating split explicitly in a software context</p></li><li><p>Provides a practice (analogous to object writing or morning pages) for the generative phase</p></li><li><p>Grounds it in a coherent theory rather than just craft wisdom</p></li></ul><p><strong>The gap it fills</strong></p><p>Agile tolerates failure tactically (iterate fast). FDD embraces failure epistemically &#8212; as the way you find out what you actually need to know. That&#8217;s a different and deeper claim.</p><p>Have you framed FDD explicitly in terms of separating the generative phase from the evaluating phase, or is that angle still implicit in the current draft?</p><h1>See Also</h1><p><em>Email</em>: <a href="mailto:ptcomputingsimplicity@gmail.com">ptcomputingsimplicity@gmail.com</a><br><em>Substack</em>: <a href="http://paultarvydas.substack.com/">paultarvydas.substack.com</a><br><em>Videos</em>: <a href="https://www.youtube.com/@programmingsimplicity2980">https://www. youtube.com/@programmingsimplicity2980</a><br><em>Discord</em>: <a href="https://discord.gg/65YZUh6Jpq">https://discord.gg/65YZUh6J. q</a><br><em>Leanpub</em>: <a href="https://leanpub.com/u/paul-tarvydas">https://leanpub.com/u/paul-tarvydas</a><br><em>Twitter</em>: @paul_tarvydas<br><em>Bluesky:</em> @paultarvydas.bsky.social<br><em>Mastodon:</em> @paultarvydas<br><em>(earlier) Blog:</em> <a href="http://guitarvydas.github.io/">guitarvydas.github.io</a><br><em>References:</em> <a href="https://guitarvydas.github.io/2024/01/06/References.html">https://guitarvydas.github.io/2024/01/06/References.html</a></p><p><em>Paid subscriptions are a voluntary way to support this work.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/p/software-development-has-a-brainstorming/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/p/software-development-has-a-brainstorming/comments"><span>Leave a comment</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/p/software-development-has-a-brainstorming?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/p/software-development-has-a-brainstorming?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/subscribe?"><span>Subscribe now</span></a></p>]]></content:encoded></item><item><title><![CDATA[One Language To Rule Them All]]></title><description><![CDATA[2026-06-03]]></description><link>https://programmingsimplicity.substack.com/p/one-language-to-rule-them-all</link><guid isPermaLink="false">https://programmingsimplicity.substack.com/p/one-language-to-rule-them-all</guid><dc:creator><![CDATA[Paul Tarvydas]]></dc:creator><pubDate>Thu, 04 Jun 2026 07:07:29 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!eSyZ!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d69eba9-d5d3-4387-a046-9b881b00bd45_131x131.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>TL;DR</strong> The functional paradigm is not general-purpose. It is specialized notation aimed at classical physics and mathematics. We mistook it for a universal foundation and spent decades bolting onto it everything it was not designed to handle. The result is bloat &#8212; measured in orders of magnitude &#8212; and a habit of removing things that worked, replacing them with things that didn&#8217;t, and quietly re-introducing the originals under new names. We never measured whether any of this was worth it.</p><div><hr></div><p><strong>L;R</strong></p><p>SICP &#8212; Structure and Interpretation of Computer Programs &#8212; is scaffolding for SICM, Structure and Interpretation of Classical Mechanics. SICM uses a programming notation to express classical mechanics. SICP builds that notation. Operating systems are scaffolding for SICP &#8212; they provide the environment in which functional programs run. Each layer solves a narrow problem well. None of it is general-purpose. It is a stack of specialized tools aimed at one target: mathematical, functional, deterministic computation.</p><p>This would be fine if we had recognized it for what it is. We did not. We declared the functional paradigm the foundation of all programming. When C made functional calling conventions standard practice for every subroutine, we stopped noticing that other conventions existed. The paradigm suited to one class of problems became the only paradigm considered for any problem.</p><p>The functional domain has a precise set of properties.</p><p>Equations are timeless. Functions are pure. State does not exist. Time does not pass. Order is irrelevant.</p><p>Classical physics is built on exactly these properties. SICP provides a notation for reasoning within these constraints. SICM uses that notation to express classical mechanics directly. The fit is exact because the domain and the notation share the same assumptions.</p><p>This is not how computers work. This is not how the internet works. This is how a single CPU works. This is how a single node in a network works. The moment you connect two CPUs, or two nodes, time reappears. State reappears. Order matters again. The functional paradigm describes one part of the machine accurately and says nothing useful about what happens between parts.</p><p>The problems began when we stretched the notation beyond its target. Re-assignment was the first major addition. In a pure functional system a variable holds one value. In the real world things change. Rather than reaching for a different notation suited to expressing change &#8212; state machines, for instance &#8212; we bolted re-assignment onto the functional paradigm. The guarantees the notation had offered began to erode. We did not get a more general tool. We got a worse functional tool with state stapled to the side.</p><p>Dynamic binding followed the same pattern. Early Lisp resolved variables at runtime, based on the call environment at the moment of execution. This was judged unpredictable and replaced with static scoping &#8212; variables resolved at compile time, based on position in the source. Static scoping made compile-time analysis possible. Type checkers and optimizers depend on it. The trade seemed like progress. Then we introduced JIT compilation. JIT makes decisions at runtime, based on what the program is actually doing. That is runtime dynamism. That is what dynamic binding did. We removed runtime flexibility in the 1960s, spent decades building tooling that assumed its absence, then spent more decades building tooling to recover it. Lisp 1.5 had this in 1962. We took a very long detour back to the same place.</p><p>Lisp 1.5, in 1962, did the core job in approximately 27 kilobytes. It had garbage collection, recursion, and a runtime evaluator. It was powerful enough to run a proof assistant. VisiCalc, in 1979, invented the spreadsheet paradigm in 20 kilobytes. Unix V1, in 1971, ran the entire operating system &#8212; kernel, shell, tools &#8212; in 24 kilobytes of total memory. Turbo Pascal 1.0, in 1983, delivered a complete IDE &#8212; editor, compiler, linker, all libraries &#8212; in a single 38-kilobyte file. These were not toys. They changed the world.</p><p>Today we speak in gigabytes. The Linux kernel exceeds 30 million lines of source code. A modern language runtime requires hundreds of megabytes before a user program loads. The footprint grew by four to five orders of magnitude. We did not ask whether we were getting four to five orders of magnitude of additional value. We assumed we were.</p><p>Sector Lisp answers the question. Sector Lisp is a modern Lisp implementation with garbage collection, written in 223 lines of assembly. Its footprint is 436 bytes. It runs the proof assistant that shipped with Lisp 1.5. The difference between gigabytes and 436 bytes is not just hardware improvement. It is the removal of everything added to function-based programming languages in the attempt to make the functional paradigm general-purpose. Sector Lisp does not allow re-assignment. It does exactly what the pure functional paradigm does, nothing more. The bloat was the generalization. The core was always small.</p><p>Type checking is the most visible symptom. We have spent decades elaborating type systems, adding annotations, and refining inference engines. The argument is that type checking catches errors before they reach production. <a href="https://www.infoq.com/presentations/dynamic-static-typing/">Robert Smallshire</a> has cited research suggesting type checking catches approximately 3 percent of real-world errors. Whether that number is exact or not, it raises a question we have not asked seriously: what did the other 97 percent cost us, and what were we doing before type checking existed?</p><p>Sketchpad, in 1963, pioneered the graphical user interface and object-oriented programming. VisiCalc transformed the personal computer into a business tool. Unix built the foundation the internet runs on. None of these were built with automated type checking. Their creators were working in notations suited to their domains &#8212; small enough to hold in one head, expressive enough to say what they meant directly. Type systems grew because languages grew because the problem domain kept expanding beyond what the original notation was designed for. With multiple small domain-specific notations, much of what the type system guards against would not exist in the first place.</p><p>This is not an argument against type checking. It is an argument that <a href="https://programmingsimplicity.substack.com/p/type-checking-is-a-symptom-not-a?r=1egdky">type checking is a symptom, not a solution</a>. The solution is to stop forcing every problem into a notation designed for a different class of problems. Build or borrow a notation that fits. Small notations can be held in one head. Small notations do not require elaborate annotation to stay consistent. Small notations, as Turbo Pascal and VisiCalc and Unix V1 showed, can change the world in under 40 kilobytes.</p><p>We did not get here by making bad decisions. We made locally reasonable decisions without measuring their cumulative cost. Each addition to the functional paradigm made sense in isolation. But we kept adding and never subtracted, never benchmarked against the baseline, never asked what we were comparing against. The baseline was 20 kilobytes and a spreadsheet that changed the world. We owe it to ourselves to compare honestly.</p><h1>See Also</h1><p><em>Email</em>: [ptcomputingsimplicity@gmail.com](mailto:ptcomputingsimplicity@gmail.com<br><em>Substack</em>: <a href="http://paultarvydas.substack.com/">paultarvydas.s. bstack.com</a><br><em>Videos</em>: <a href="https://www.youtube.com/@programmingsimplicity2980">https://www. youtube.com/@programmingsimplicity2980</a><br><em>Discord</em>: <a href="https://discord.gg/65YZUh6Jpq">https://discord.gg/65YZUh6J. q</a><br><em>Leanpub</em>: <a href="https://leanpub.com/u/paul-tarvydas">https:. /leanpub.com/u/paul-tarvydas</a><br><em>Twitter</em>: @paul_tarvydas<br><em>Bluesky:</em> @paultarvydas.bsky.social<br><em>Mastodon:</em> @paultarvydas<br><em>(earlier) Blog:</em> <a href="http://guitarvydas.github.io/">guitarvydas.github.io</a><br><em>References:</em> <a href="https://guitarvydas.github.io/2024/01/06/References.html">https://guitarvydas.github.io/2024/01/06/References.html</a></p><p><em>Paid subscriptions are a voluntary way to support this work.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/p/one-language-to-rule-them-all/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/p/one-language-to-rule-them-all/comments"><span>Leave a comment</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/p/one-language-to-rule-them-all?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/p/one-language-to-rule-them-all?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/subscribe?"><span>Subscribe now</span></a></p>]]></content:encoded></item><item><title><![CDATA[We Painted Ourselves Into a Corner]]></title><description><![CDATA[2026-06-03]]></description><link>https://programmingsimplicity.substack.com/p/we-painted-ourselves-into-a-corner</link><guid isPermaLink="false">https://programmingsimplicity.substack.com/p/we-painted-ourselves-into-a-corner</guid><dc:creator><![CDATA[Paul Tarvydas]]></dc:creator><pubDate>Wed, 03 Jun 2026 13:00:24 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!eSyZ!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d69eba9-d5d3-4387-a046-9b881b00bd45_131x131.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>TL;DR</strong> Synchronous, sequential notation has colonized all of modern programming. Every mainstream language &#8212; Python, JavaScript, Haskell, Rust, Clojure &#8212; is the same at the core: sync. Once you commit to sync, asynchrony is not just inconvenient to recover; it is structurally unrecoverable. We have compounded this by treating analysis-oriented notation as if it were expression-oriented notation. The result is that we are solving 21st-century problems with 20th-century tools, pasting bandaids on bandaids, and calling it progress.</p><div><hr></div><p><strong>L;R</strong></p><p>Python, JavaScript, Haskell, Rust, Clojure. These languages look different. They feel different. Their communities are different. But they are the same at the core: every one of them is built on the synchronous, sequential paradigm. This paradigm is not a feature of these languages &#8212; it is the water they swim in. It permeates every language decision, every library design, every idiom. The differences between these languages are lipstick on the same pig.</p><p>The mechanism is simple. As soon as you write a function that calls another function, you have committed to synchronous control flow. The callee runs. The caller waits. Time is implicit. Order is enforced. On paper &#8212; where the laws of physics do not apply to notation &#8212; this works fine as a simplification. But when you map this onto real, physical hardware, the implicit assumptions start leaking. The hardware does not wait. The network does not wait. The user does not wait. And no amount of async/await sugar, thread libraries, or reactive frameworks recovers what was lost when you wrote that first function call. You cannot put asynchrony back into a notation that has already committed it away.</p><p>This is not a theoretical complaint. It shows up as &#8220;callback hell.&#8221; It shows up as cache coherence problems and thread-safety rituals. It shows up as the entire edifice of concurrency primitives &#8212; semaphores, mutexes, futures, promises &#8212; which exist not because concurrency is complicated, but because we chose a notation that cannot express it directly, and then spent decades building scaffolding to work around that choice. We painted ourselves into a corner and responded by building more elaborate furniture to stand on.</p><p>A five-year-old taking piano lessons understands something that a senior software engineer, working in a modern language, cannot directly express. The child learns to get the left hand and the right hand to play different notes at the same time &#8212; not sequentially, not taking turns, but concurrently, each following its own rhythm. The child learns hard realtime: notes must land at exactly the right moment. The child learns a notation &#8212; standard musical notation &#8212; that captures all of this succinctly. Duration, timing, concurrency, relative ordering: one page of sheet music expresses what no mainstream programming language can express without significant ceremony. The five-year-old&#8217;s intuition is a tell. The problem is not complicated. Our notation made it complicated.</p><p>We have not only chosen a paradigm poorly suited to concurrency. We have allowed the demands of analysis to colonize the demands of expression. These are different things. A notation suited to analyzing a concept is not necessarily suited to expressing that concept in a running system, and vice versa. David Harel&#8217;s Statecharts are the clearest demonstration I know of how analysis can destroy the very thing it sets out to formalize. Harel&#8217;s original statechart paper gave us a notation that expressed asynchronous parallelism directly. States, transitions, hierarchy, concurrency &#8212; all visible, all expressible in a diagram. His follow-up micro-semantics paper formalized the concept analytically. In doing so, it forced sequentiality onto the model. The asynchronous parallelism of Statecharts was converted into synchronous concurrency. The formalization was correct analytically and useless practically. I discovered this early on, trying to use the formalized version in a real, live, asynchronous system. The analysis had eaten the property I needed.</p><p>The same pattern appears in pBFT &#8212; Castro and Liskov&#8217;s 1999 solution to the Byzantine Generals Problem, which influenced several blockchain implementations.. The concept at the heart of pBFT is actually two concepts: cryptographic constructs for encryption, and state-machine constructs for the ebb and flow of node participation, drop-in, and drop-out. The cryptographic part is naturally expressed in mathematical, functional notation. The state-machine part is naturally expressed as a state machine &#8212; or better, a Statechart. But the paper was written in one notation. The state-machine behavior was forced into the same synchronous sequential framework as the encryption. The extra work required to do this was not free. The brain power spent on the impedance mismatch was brain power not spent on other problems.</p><p>A simpler example: I built a three-state state machine and expressed it as a diagram. The same machine, transcribed into Python, runs to approximately sixty lines of code. A seasoned Python programmer could trim that number. But no amount of trimming recovers what the diagram gives for free: the visual structure of the states, the transitions, the conditions, all immediately apparent to anyone who looks. The Python version is not wrong. It is a different notation, and it obfuscates the information that the diagram expresses directly. We use the wrong notation and then spend effort reconstructing what a better notation would have given us at no cost.</p><p>The same principle, this time with a textual notation: Forth Haiku. Two lines of Forth Haiku control a GPU as well as a hundred lines of GLSL and JavaScript. This is not a party trick. It is a demonstration that a notation suited to its domain can be radically more expressive than a general-purpose notation applied to the same domain. Critically, generalizing Forth Haiku &#8212; trying to make it do everything &#8212; would produce a mess. Exponential growth of code. The mess is a tell. The right lesson is not to generalize Forth Haiku. The right lesson is that domain-specific notation, applied with discipline, beats general-purpose notation applied with force.</p><p>Casey Muratori and the Handmade Network have been making a version of this argument from the direction of games programming: our current programming languages are not well suited to building games. The gaming industry&#8217;s response has been to work around the languages, not with them. This is the same pattern everywhere. The workarounds are not solutions. They are evidence that the foundation is wrong.</p><p>We tell ourselves we are standing on the shoulders of giants. In many cases we are. But the giants were solving single-CPU, synchronous, sequential problems. Their shoulders point in one direction. The problems of the 21st century &#8212; distributed systems, asynchronous networks, multi-core concurrency, real-time interaction &#8212; are in a different direction entirely. Continuing to build on those shoulders, in those notations, is not progress. It is the definition of doing the same thing over and over and expecting different results.</p><p>The prescription is not a new general-purpose language. The prescription is to stop insisting on one. Use synchronous notation where synchronous notation fits: mathematical expression, encryption, pure function. Use state-based notation where state-based notation fits: control flow, lifecycle, protocol. Use diagram-based notation where diagrams carry information that text cannot. Use whatever notation is suited to the part of the problem you are solving. Match the notation to the domain, not the domain to the notation. Build a small, cheap, custom notation when none of the existing ones fit. OhmJS and PEG parsers make this as accessible as writing a regular expression.</p><p>We have the tools. We have the intuition &#8212; five-year-olds have it. What we are missing is the permission to stop treating one notation as the answer to every question.</p><h1>References</h1><p><a href="https://guitarvydas.github.io/2023/11/27/Statecharts-Papers-We-Love-Video.html">Statecharts PWL video</a><br><a href="https://www.weizmann.ac.il/math/harel/sites/math.harel/files/users/user56/FormalSemanticsStatecharts.pdf">microsemantics of Statecharts</a><br><a href="https://www.youtube.com/watch?v=wo84LFzx5nI">Muratori &#8220;The Big OOPs - Anatomy of a Thirty-Five Year Mistake&#8221;</a><br><a href="https://www.youtube.com/playlist?list=PLHh2_dCKBPjaA3z6dC8tntQE3ypp_7Wvm">Forth Haiku video playlist</a><br><a href="https://youtu.be/CE6zkNTZYro">3 state state machine video (convert state machine diagram to Python)</a></p><h1>See Also</h1><p><em>Email</em>: <a href="mailto:ptcomputingsimplicity@gmail.com">ptcomputingsimplicity@gmail.com</a><br><em>Substack</em>: <a href="http://paultarvydas.substack.com/">paultarvydas.substack.com</a><br><em>Videos</em>: <a href="https://www.youtube.com/@programmingsimplicity2980">https://www.youtube.com/@programmingsimplicity2980</a><br><em>Discord</em>: <a href="https://discord.gg/65YZUh6Jpq">https://discord.gg/65YZUh6Jpq</a><br><em>Leanpub</em>: [WIP] <a href="https://leanpub.com/u/paul-tarvydas">https://leanpub.com/u/paul-tarvydas</a><br><em>Twitter</em>: @paul_tarvydas<br><em>Bluesky:</em> @paultarvydas.bsky.social<br><em>Mastodon:</em> @paultarvydas<br><em>(earlier)</em> <em>Blog:</em> <a href="http://guitarvydas.github.io/">guitarvydas.github.io</a><br><em>References:</em> <a href="https://guitarvydas.github.io/2024/01/06/References.html">https://guitarvydas.github.io/2024/01/06/References.html</a></p><p><em>Paid subscriptions are a voluntary way to support this work.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/p/we-painted-ourselves-into-a-corner/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/p/we-painted-ourselves-into-a-corner/comments"><span>Leave a comment</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/p/we-painted-ourselves-into-a-corner?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/p/we-painted-ourselves-into-a-corner?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/subscribe?"><span>Subscribe now</span></a></p>]]></content:encoded></item><item><title><![CDATA[Words]]></title><description><![CDATA[2026-06-01]]></description><link>https://programmingsimplicity.substack.com/p/words</link><guid isPermaLink="false">https://programmingsimplicity.substack.com/p/words</guid><dc:creator><![CDATA[Paul Tarvydas]]></dc:creator><pubDate>Mon, 01 Jun 2026 12:03:33 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!eSyZ!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d69eba9-d5d3-4387-a046-9b881b00bd45_131x131.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>One must be careful to understand that words carry much more baggage than just their literal dictionary meaning.</p><p>In songwriting, I was taught to lean heavily on the thesaurus for several reasons, such as<br>- syllable count, and syllable emphasis to match underlying melody flow<br>- plosives, fricatives, etc., to evoke &#8220;feeling&#8221; that matches with the rest of the intent of the song<br>- brainstorming - just <em>looking</em> at synonyms can trigger thoughts and new ideas on a custom / personal basis<br>- rhymes and B-rhymes<br>- imagery</p><p>There are lots of examples of this kind of thing, but I most reminded of Robert Frost&#8217;s &#8220;The Span of Life&#8221; - a two-line poem that evokes lots of imagery:</p><blockquote><p>The old dog barks backwards without getting up.<br>I can remember when he was a pup.</p></blockquote><p>For example, note that &#8220;barks&#8221; ends in a fricative &#8220;s&#8221; which allows a smooth flow into &#8220;backwards&#8221;. Both words begin with a plosive &#8220;b&#8221; which makes the phrase pop out and evoke the image of barking. There&#8217;s lots more going on here&#8230;</p><p>Lispers tend to use long names in code, whereas non-lispers see this as being verbose. &#8220;Ret&#8221; instead of &#8220;return&#8221; can be a readability issue as well as a writability issue (akin to the use of Greek letters in math).</p><p>Inference: each consumer of words can get a completely different meaning from a phrase, hence, one cannot always achieve perfect transmission of intent. Great songwriters make their songs touch many people, great software architects arrange designs in ways that are more readable. Great code is not always great architecture. Code is for machines. Arrangement of code to express design intent is for people.</p><h1>See Also</h1><p><em>Email</em>: [ptcomputingsimplicity@gmail.com](mailto:ptcomputingsimplicity@gmail.com<br><em>Substack</em>: <a href="http://paultarvydas.substack.com/">paultarvydas.s. bstack.com</a><br><em>Videos</em>: <a href="https://www.youtube.com/@programmingsimplicity2980">https://www. youtube.com/@programmingsimplicity2980</a><br><em>Discord</em>: <a href="https://discord.gg/65YZUh6Jpq">https://discord.gg/65YZUh6J. q</a><br><em>Leanpub</em>: <a href="https://leanpub.com/u/paul-tarvydas">https:. /leanpub.com/u/paul-tarvydas</a><br><em>Twitter</em>: @paul_tarvydas<br><em>Bluesky:</em> @paultarvydas.bsky.social<br><em>Mastodon:</em> @paultarvydas<br><em>(earlier) Blog:</em> <a href="http://guitarvydas.github.io/">guitarvydas.github.io</a><br><em>References:</em> <a href="https://guitarvydas.github.io/2024/01/06/References.html">https://guitarvydas.github.io/2024/01/06/References.html</a></p><p><em>Paid subscriptions are a voluntary way to support this work.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/subscribe?"><span>Subscribe now</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/p/words?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/p/words?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/p/words/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/p/words/comments"><span>Leave a comment</span></a></p><p></p>]]></content:encoded></item><item><title><![CDATA[Computation vs. The Arrow of Time]]></title><description><![CDATA[2026-05-31]]></description><link>https://programmingsimplicity.substack.com/p/computation-vs-the-arrow-of-time</link><guid isPermaLink="false">https://programmingsimplicity.substack.com/p/computation-vs-the-arrow-of-time</guid><dc:creator><![CDATA[Paul Tarvydas]]></dc:creator><pubDate>Mon, 01 Jun 2026 02:09:40 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!eSyZ!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d69eba9-d5d3-4387-a046-9b881b00bd45_131x131.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In the book &#8220;Order Out of Chaos&#8221; authors Ilya Prigogene (Nobel laureate) and Isabelle Stengers state that functional thinking - function-based notation - has set physics back by 100 years.</p><p>I feel that the same is happening in Computer Science.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Programming Simplicity is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>I used to think that Computer Science was a study of the way to express what reprogrammable machines (RMs) could do.</p><p>I no longer think so. I see Computer Science as the study of how to formalize computational thinking and of how to <em>use</em> reprogrammable machines as building materials to build machines for computation, i.e. &#8220;compute-ers&#8221; instead of a study of what reprogrammable machines are capable of.</p><p>Lisp 1.5 was an exposition of how to <em>use</em> assembler-based CPUs to build machines for computing within the functional paradigm, where only the result matters and the zig-zag, irreversible path of how that result was achieved is elided and ignored. In my view, Computer Science is just an extension and further refinement and modernization of this notion.</p><p>I see this as a form of notation worship. The intent seems to be to thread <em>every</em> problem through the eye of the needle of the synchronous, sequential paradigm, regardless of how much accidental complexity this causes.</p><p>This is but a one-way mapping. You can <em>use</em> CPUs to create machines for computation, but you can&#8217;t use synchronous, sequential computation to express the composition of the asynchronous parts that make up a laptop or an internet. You <em>can</em> use current synchronous, sequential programming languages to create <em>parts</em> of a laptop - e.g. the CPU-based part - or <em>parts</em> of the internet (i.e. one <em>node</em>) - but you can&#8217;t actually express the composition of the whole, since that involves components that run asynchronously - which is - by definition - swept off the table by the underlying model of synchronous, sequential paradigm.</p><p>To express async composition, we use electronic schematics. Schematics allow for the combination of asynchronous units, like disks, CPUs, keyboards, displays, etc. Schematics ain&#8217;t perfect as a notation, but at least they don&#8217;t prematurely discard asynchronous non-sequential operation.</p><p>Inventing constructs like &#8220;async/await&#8221; in programming languages allows us to describe reactive elements that work synchronously internally but can only be coupled together in a laborious, assembler-like fashion, into compositions of asynchronously-operating units. This will never achieve the expression of the composition of async elements - something &#8220;above&#8221; and outside of the capabilities of what we currently call programming languages. Programming deals only with the synchronous, sequential action of a single <em>node</em> in an asynchronous system, it does not deal with the whole async system.</p><p>Multi-threading as we know it cannot be parallelism, it is only a collection of interleaved functional threads that work so quickly as to fool us into perceiving that they are working in parallel.</p><p>Example: Prolog is a non-functional language. Prolog uses synchronous, sequential programming languages, of the ilk of assembler, C, Haskell, Clojure, Rust, etc., as building materials to construct an <em>engine</em> for relational expression and thinking. Prolog builds relational engines using synchronous, sequential programming languages, but can never express whole parallel relational machines since asynchronousity has already been removed due to the underlying synchronous, sequential substrate.</p><p>I assert that continuing to use current synchronous, sequential programming languages to deal with asynchronous systems is a death march. It only <em>looks</em> like we are dealing with asynchronous, non-sequential issues, but, by using synchronous, sequential programming languages we remove asynchronousity and cherry pick problems and solutions that are already amenable to that kind of approach - a thin slice of what&#8217;s actually possible. This kind of cherry picking is causing us to miss the forest for the trees.</p><p>Arrow of time: the synchronous, sequential paradigm is a spherical cow that excludes the arrow of time for computational convenience. Once you throw out the arrow of time, you can&#8217;t put it back. You can put fake constructs like timestamps into the synchronous, sequential expression of systems, but in reality, the arrow of time is gone.</p><h1>See Also</h1><p><em>Email</em>: [ptcomputingsimplicity@gmail.com](mailto:ptcomputingsimplicity@gmail.com<br><em>Substack</em>: <a href="http://paultarvydas.substack.com/">paultarvydas.s. bstack.com</a><br><em>Videos</em>: <a href="https://www.youtube.com/@programmingsimplicity2980">https://www. youtube.com/@programmingsimplicity2980</a><br><em>Discord</em>: <a href="https://discord.gg/65YZUh6Jpq">https://discord.gg/65YZUh6J. q</a><br><em>Leanpub</em>: <a href="https://leanpub.com/u/paul-tarvydas">https:. /leanpub.com/u/paul-tarvydas</a><br><em>Twitter</em>: @paul_tarvydas<br><em>Bluesky:</em> @paultarvydas.bsky.social<br><em>Mastodon:</em> @paultarvydas<br><em>(earlier) Blog:</em> <a href="http://guitarvydas.github.io/">guitarvydas.github.io</a><br><em>References:</em> <a href="https://guitarvydas.github.io/2024/01/06/References.html">https://guitarvydas.github.io/2024/01/06/References.html</a></p><p><em>Paid subscriptions are a voluntary way to support this work.</em></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Programming Simplicity is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Concurrency Is Not Parallelism]]></title><description><![CDATA[2026-05-26]]></description><link>https://programmingsimplicity.substack.com/p/concurrency-is-not-parallelism</link><guid isPermaLink="false">https://programmingsimplicity.substack.com/p/concurrency-is-not-parallelism</guid><dc:creator><![CDATA[Paul Tarvydas]]></dc:creator><pubDate>Tue, 26 May 2026 08:46:23 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!2LNQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13eec873-7e22-4304-901a-7e762352af1c_371x351.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1><strong>TL;DR</strong></h1><p> In casual English, &#8220;concurrency&#8221; and &#8220;parallelism&#8221; are used interchangeably. In computer science, the distinction is precise and consequential. Synchronous functions cannot &#8212; as in <em>impossible</em> &#8212; express asynchronous activities. Multi-threading fakes parallelism; PBP (0D) designs software that is ready for true parallelism from the start.</p><div><hr></div><h1>L;R</h1><h2>Analogy</h2><p>Consider what a data <em>record</em> looks like in memory: A struct (class, record) written in code looks benign. Mapped onto 64-bit hardware and emitted as aligned data, gaps appear in the memory layout between fields.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!b5KA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2626145-9bdd-4e4d-9d9c-1b7e20092763_691x251.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!b5KA!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2626145-9bdd-4e4d-9d9c-1b7e20092763_691x251.png 424w, https://substackcdn.com/image/fetch/$s_!b5KA!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2626145-9bdd-4e4d-9d9c-1b7e20092763_691x251.png 848w, https://substackcdn.com/image/fetch/$s_!b5KA!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2626145-9bdd-4e4d-9d9c-1b7e20092763_691x251.png 1272w, https://substackcdn.com/image/fetch/$s_!b5KA!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2626145-9bdd-4e4d-9d9c-1b7e20092763_691x251.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!b5KA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2626145-9bdd-4e4d-9d9c-1b7e20092763_691x251.png" width="691" height="251" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c2626145-9bdd-4e4d-9d9c-1b7e20092763_691x251.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:251,&quot;width&quot;:691,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!b5KA!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2626145-9bdd-4e4d-9d9c-1b7e20092763_691x251.png 424w, https://substackcdn.com/image/fetch/$s_!b5KA!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2626145-9bdd-4e4d-9d9c-1b7e20092763_691x251.png 848w, https://substackcdn.com/image/fetch/$s_!b5KA!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2626145-9bdd-4e4d-9d9c-1b7e20092763_691x251.png 1272w, https://substackcdn.com/image/fetch/$s_!b5KA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2626145-9bdd-4e4d-9d9c-1b7e20092763_691x251.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Some languages and compilers allow programmers to &#8220;pack&#8221; the data to eliminate those gaps. This saves memory but costs compute cycles, because the CPU works harder to access data not aligned on 64-bit boundaries.</p><p>The same phenomenon appears in multi-threading &#8212; except the gaps are in the dimension of <em>time</em>, not space. The principle is identical: optimization choices in one dimension create costs in another.</p><h2>Multi-Threading Fakes Parallelism</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2LNQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13eec873-7e22-4304-901a-7e762352af1c_371x351.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2LNQ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13eec873-7e22-4304-901a-7e762352af1c_371x351.png 424w, https://substackcdn.com/image/fetch/$s_!2LNQ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13eec873-7e22-4304-901a-7e762352af1c_371x351.png 848w, https://substackcdn.com/image/fetch/$s_!2LNQ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13eec873-7e22-4304-901a-7e762352af1c_371x351.png 1272w, https://substackcdn.com/image/fetch/$s_!2LNQ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13eec873-7e22-4304-901a-7e762352af1c_371x351.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2LNQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13eec873-7e22-4304-901a-7e762352af1c_371x351.png" width="371" height="351" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/13eec873-7e22-4304-901a-7e762352af1c_371x351.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:351,&quot;width&quot;:371,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!2LNQ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13eec873-7e22-4304-901a-7e762352af1c_371x351.png 424w, https://substackcdn.com/image/fetch/$s_!2LNQ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13eec873-7e22-4304-901a-7e762352af1c_371x351.png 848w, https://substackcdn.com/image/fetch/$s_!2LNQ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13eec873-7e22-4304-901a-7e762352af1c_371x351.png 1272w, https://substackcdn.com/image/fetch/$s_!2LNQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13eec873-7e22-4304-901a-7e762352af1c_371x351.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Each &#8220;thread&#8221; is an isolated function. Such functions call other functions within the same thread in a synchronous, sequential manner.</p><p>Extra software &#8212; the operating system &#8212; divvies up CPU time and hands slices of it to all threads running on the same machine.</p><p>This happens fast enough that humans perceive the threads as running in parallel. They are not. They run sequentially, and slower than they could, due to the overhead of the operating system.</p><p>We have been extracting performance from this model by adding complex caches, multiple cores, and cache coherency logic. Code running in the L1 caches of separate cores can run in parallel, but becomes sequential and synchronous the moment it accesses data outside those caches. One machine does not run multiple threads in a truly parallel manner.</p><h2>True Parallelism Requires Dedicated CPUs</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!eBPK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F589fd73e-e16a-4b51-ad5f-16fddba71391_411x296.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!eBPK!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F589fd73e-e16a-4b51-ad5f-16fddba71391_411x296.png 424w, https://substackcdn.com/image/fetch/$s_!eBPK!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F589fd73e-e16a-4b51-ad5f-16fddba71391_411x296.png 848w, https://substackcdn.com/image/fetch/$s_!eBPK!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F589fd73e-e16a-4b51-ad5f-16fddba71391_411x296.png 1272w, https://substackcdn.com/image/fetch/$s_!eBPK!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F589fd73e-e16a-4b51-ad5f-16fddba71391_411x296.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!eBPK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F589fd73e-e16a-4b51-ad5f-16fddba71391_411x296.png" width="411" height="296" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/589fd73e-e16a-4b51-ad5f-16fddba71391_411x296.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:296,&quot;width&quot;:411,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!eBPK!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F589fd73e-e16a-4b51-ad5f-16fddba71391_411x296.png 424w, https://substackcdn.com/image/fetch/$s_!eBPK!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F589fd73e-e16a-4b51-ad5f-16fddba71391_411x296.png 848w, https://substackcdn.com/image/fetch/$s_!eBPK!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F589fd73e-e16a-4b51-ad5f-16fddba71391_411x296.png 1272w, https://substackcdn.com/image/fetch/$s_!eBPK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F589fd73e-e16a-4b51-ad5f-16fddba71391_411x296.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>True parallelism means one CPU per thread. In that case, no operating system overhead is needed on each machine.</p><p>This was the goal of hardware architects in the early days of computing. CPUs and whole computers were too expensive to justify it then.</p><p>Today, CPUs are cheap. Arduinos, ESP32s, and Raspberry Pis are cheap. The economic justification for complicated software that squeezes cycles out of shared hardware is gone.</p><p>The internet already works this way. Internet nodes are separate, totally isolated computers that run at their own speed and exchange blobs of data as messages.</p><p>We continue using old-fashioned shared-memory ideas because, as <a href="https://programmingsimplicity.substack.com/p/capt-grace-hopper-on-future-possibilities?r=1egdky">Grace Hopper</a> put it, &#8220;we&#8217;ve always done it this way&#8221;.</p><h2>PBP &#8212; Parts-Based Programming</h2><p>PBP (0D) simulates software meant to run in parallel, on a single machine, in a way that is ready to split off onto separate machines.</p><p>The key fact: synchronous functions cannot express asynchronous activities. Fake parallelism expressed as concurrency in the functional paradigm works the way Disney cartoons work &#8212; by fooling human perception into seeing motion that is not there.</p><p>In the early days of stand-alone computers, we chose small-grained memory sharing over message passing. The earliest symptom of that choice was &#8220;thread safety&#8221;. Symptoms have been popping up in whack-a-mole fashion ever since &#8212; callback hell, the Mars Pathfinder fiasco &#8212; and each time, we applied a band-aid instead of fixing the basic problem. The problems of thread safety evaporate when isolated computers are used. Programming complexity drops when thread safety no longer inflicts itself on thought patterns, language design, and operating system architecture.</p><p>Early cartridge-based gaming systems had no operating systems and were fundamentally simpler to program. The invention of the operating system was a soft substitute for a machine with multiple slots, each with its own isolated CPU, with mechanical switches to route shared hardware resources &#8212; displays, keyboards, joysticks &#8212; between programs. We built the switch in software and called it an OS. PBP goes back to the hardware intuition: isolated components, explicit wiring, message passing. No shared memory. No thread safety. No operating system required.</p><h1>See Also</h1><p><em>Email</em>: <a href="mailto:ptcomputingsimplicity@gmail.com">ptcomputingsimplicity@gmail.com</a> <em>Substack</em>: <a href="http://paultarvydas.substack.com/">paultarvydas.s. bstack.com</a> <em>Videos</em>: <a href="https://www.youtube.com/@programmingsimplicity2980">https://www. youtube.com/@programmingsimplicity2980</a> <em>Discord</em>: <a href="https://discord.gg/65YZUh6Jpq">https://discord.gg/65YZUh6J. q</a><br><em>Leanpub</em>: <a href="https://leanpub.com/u/paul-tarvydas">https://leanpub.com/u/paul-tarvydas</a><br><em>Twitter</em>: @paul_tarvydas<br><em>Bluesky:</em> @paultarvydas.bsky.social<br><em>Mastodon:</em> @paultarvydas<br><em>(earlier) Blog:</em> <a href="http://guitarvydas.github.io/">guitarvydas.github.io</a><br><em>References:</em> <a href="https://guitarvydas.github.io/2024/01/06/References.html">https://guitarvydas.github.io/2024/01/06/References.html</a></p><p><em>Paid subscriptions are a voluntary way to support this work.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/subscribe?"><span>Subscribe now</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/p/concurrency-is-not-parallelism?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/p/concurrency-is-not-parallelism?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/p/concurrency-is-not-parallelism/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/p/concurrency-is-not-parallelism/comments"><span>Leave a comment</span></a></p><p></p>]]></content:encoded></item><item><title><![CDATA[FDD - Failure Driven Development]]></title><description><![CDATA[2026-05-24]]></description><link>https://programmingsimplicity.substack.com/p/fdd-failure-driven-development</link><guid isPermaLink="false">https://programmingsimplicity.substack.com/p/fdd-failure-driven-development</guid><dc:creator><![CDATA[Paul Tarvydas]]></dc:creator><pubDate>Sun, 24 May 2026 21:57:26 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!eSyZ!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d69eba9-d5d3-4387-a046-9b881b00bd45_131x131.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>We can now stop worrying about &#8220;code&#8221; and worry a lot more about &#8220;design&#8221;. That&#8217;s the main point of Failure Driven Development.</p><p>PBP is one of the tools for FDD - snap parts together like LEGO blocks and see if you like the result. If not, knock it all down and start all over again. Repeat numerous times.</p><p>I&#8217;ve been using Claude to argue with me. To be a foil that espouses the &#8220;functional approach&#8221; to writing code.</p><p>The biggest fall-out of these brain-storming sessions is the observation that PBP goes a step further than Erlang by providing &#8220;topology blindness&#8221;. It is a core term in the PBP/0D vocabulary, describing the property that components do not know their own neighbors and that wiring is controlled by the parent container rather than by the components themselves.</p><p>To implement topology blindness, it is more convenient to roll your own multi-tasking kernel, instead of relying on existing thread libraries, and, you need to create a system of two-tier &#8220;parts&#8221; that I call Container parts and Leaf parts.</p><h1>See Also</h1><p><em>Email</em>: <a href="mailto:ptcomputingsimplicity@gmail.com">ptcomputingsimplicity@gmail.com</a><br><em>Substack</em>: <a href="http://paultarvydas.substack.com/">paultarvydas.substack.com</a><br><em>Videos</em>: <a href="https://www.youtube.com/@programmingsimplicity2980">https://www.youtube.com/@programmingsimplicity2980</a><br><em>Discord</em>: <a href="https://discord.gg/65YZUh6Jpq">https://discord.gg/65YZUh6Jpq</a><br><em>Leanpub</em>: <a href="https://leanpub.com/u/paul-tarvydas">https://leanpub.com/u/paul-tarvydas</a><br><em>Twitter</em>: @paul_tarvydas<br><em>Bluesky:</em> @paultarvydas.bsky.social<br><em>Mastodon:</em> @paultarvydas<br><em>(earlier)</em> <em>Blog:</em> <a href="http://guitarvydas.github.io/">guitarvydas.github.io</a><br><em>References:</em><a href="https://guitarvydas.github.io/2024/01/06/References.html">https://guitarvydas.github.io/2024/01/06/References.html</a></p><p><em>Paid subscriptions are a voluntary way to support this work.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/p/fdd-failure-driven-development/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/p/fdd-failure-driven-development/comments"><span>Leave a comment</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/p/fdd-failure-driven-development?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/p/fdd-failure-driven-development?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/subscribe?"><span>Subscribe now</span></a></p>]]></content:encoded></item><item><title><![CDATA[Ideas for Porting PBP to Go]]></title><description><![CDATA[2026-05-24]]></description><link>https://programmingsimplicity.substack.com/p/ideas-for-porting-pbp-to-go</link><guid isPermaLink="false">https://programmingsimplicity.substack.com/p/ideas-for-porting-pbp-to-go</guid><dc:creator><![CDATA[Paul Tarvydas]]></dc:creator><pubDate>Sun, 24 May 2026 21:48:09 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!eSyZ!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d69eba9-d5d3-4387-a046-9b881b00bd45_131x131.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I&#8217;ve written the PBP kernel in a pseudo-language and generate Python, JS and CL. I think that if you were to point your LLM at</p><ul><li><p><a href="https://github.com/guitarvydas/pbp-dev/blob/main/kernel/0d.rt">https://github.com/guitarvydas/pbp-dev/blob/main/kernel/0d.rt</a>,</p></li><li><p><a href="https://github.com/guitarvydas/pbp-dev/blob/main/kernel/stock.rt">https://github.com/guitarvydas/pbp-dev/blob/main/kernel/stock.rt</a> and</p></li><li><p><a href="https://github.com/guitarvydas/pbp-dev/blob/main/kernel/jit.rt">https://github.com/guitarvydas/pbp-dev/blob/main/kernel/jit.rt</a></p></li></ul><p>and gave it the Python versions</p><ul><li><p><a href="https://github.com/guitarvydas/pbp-dev/blob/main/kernel/0d.py">https://github.com/guitarvydas/pbp-dev/blob/main/kernel/0d.py</a>,</p></li><li><p><a href="https://github.com/guitarvydas/pbp-dev/blob/main/kernel/stock.py">https://github.com/guitarvydas/pbp-dev/blob/main/kernel/stock.py</a> and</p></li><li><p><a href="https://github.com/guitarvydas/pbp-dev/blob/main/kernel/jit.py">https://github.com/guitarvydas/pbp-dev/blob/main/kernel/jit.py</a>,</p></li></ul><p>it might be able to infer the Go version.</p><p>Maybe you also need to give it the Ohm grammar file</p><ul><li><p><a href="https://github.com/guitarvydas/pbp-dev/blob/main/kernel/emit.ohm">https://github.com/guitarvydas/pbp-dev/blob/main/kernel/emit.ohm</a></p></li></ul><p>and the Python rewrite rules</p><ul><li><p><a href="https://github.com/guitarvydas/pbp-dev/blob/main/kernel/emitPython.rwr">https://github.com/guitarvydas/pbp-dev/blob/main/kernel/emitPython.rwr</a></p></li></ul><p>I suspect that using words like &#8220;concurrent&#8221; and &#8220;process&#8221; and &#8220;thread&#8221; might get an LLM to generate convoluted / wrong code. 0D.rt implements its own form of multi-processing from scratch - don&#8217;t let an LLM use preconceived ideas about what threads are. Threading needs only 10&#8217;s of lines of code - all existing thread libraries that I know of (including Go) have turned this into a behemoth, steaming pile of complexity.</p><p>If you do need to use words like these, tell the LLM to use a mutual multi-tasking model (aka &#8220;green threads&#8221;) with NO shared memory. A lot of the cancerous complexity growth has befallen us because of the use of implicit memory sharing (starting with the concept of &#8220;thread safety&#8221;). When you strip the underlying memory sharing assumption out, the code becomes orders of magnitude simpler. The first kernel I studied was 1/2 page of assembler code.</p><h1>See Also</h1><p><em>Email</em>: <a href="mailto:ptcomputingsimplicity@gmail.com">ptcomputingsimplicity@gmail.com</a><br><em>Substack</em>: <a href="http://paultarvydas.substack.com/">paultarvydas.substack.com</a><br><em>Videos</em>: <a href="https://www.youtube.com/@programmingsimplicity2980">https://www.youtube.com/@programmingsimplicity2980</a><br><em>Discord</em>: <a href="https://discord.gg/65YZUh6Jpq">https://discord.gg/65YZUh6Jpq</a><br><em>Leanpub</em>: <a href="https://leanpub.com/u/paul-tarvydas">https://leanpub.com/u/paul-tarvydas</a><br><em>Twitter</em>: @paul_tarvydas<br><em>Bluesky:</em> @paultarvydas.bsky.social<br><em>Mastodon:</em> @paultarvydas<br><em>(earlier)</em> <em>Blog:</em> <a href="http://guitarvydas.github.io/">guitarvydas.github.io</a><br><em>References:</em> <a href="https://guitarvydas.github.io/2024/01/06/References.html">https://guitarvydas.github.io/2024/01/06/References.html</a></p><p><em>Paid subscriptions are a voluntary way to support this work.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/p/ideas-for-porting-pbp-to-go/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/p/ideas-for-porting-pbp-to-go/comments"><span>Leave a comment</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/p/ideas-for-porting-pbp-to-go?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/p/ideas-for-porting-pbp-to-go?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/subscribe?"><span>Subscribe now</span></a></p>]]></content:encoded></item><item><title><![CDATA[Forth Haiku Compendium]]></title><description><![CDATA[2026-05-17]]></description><link>https://programmingsimplicity.substack.com/p/forth-haiku-compendium</link><guid isPermaLink="false">https://programmingsimplicity.substack.com/p/forth-haiku-compendium</guid><dc:creator><![CDATA[Paul Tarvydas]]></dc:creator><pubDate>Sun, 17 May 2026 08:35:49 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!eSyZ!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d69eba9-d5d3-4387-a046-9b881b00bd45_131x131.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1>Forth Haiku Compendium</h1><p>These have been already published in substack and on YouTube.</p><p>This is but a summary for convenience.</p><p><a href="https://programmingsimplicity.substack.com/p/diy-forth-forth-haiku-analysis-part?r=1egdky">Forth Haiku Analysis Part 1</a><br><a href="https://programmingsimplicity.substack.com/p/diy-forth-forth-haiku-analysis-part-897?r=1egdky">Forth Haiku Analysis Part 2</a><br><a href="https://programmingsimplicity.substack.com/p/forth-haiku-optimizer?r=1egdky">Forth Haiku Optimizer</a><br><a href="https://programmingsimplicity.substack.com/p/forth-haiku-gpu-and-cpu-pipelines?r=1egdky">Forth Haiku CPU and GPU Pipelines</a><br><a href="https://programmingsimplicity.substack.com/p/what-ive-learned-from-forth-haiku?r=1egdky">What I&#8217;ve Learned From Forth Haiku Thus Far</a></p><p>youtube playlist (duplicates of above videos, without the rest of the text supplied in the substack articles)<br><a href="https://www.youtube.com/playlist?list=PLHh2_dCKBPjaA3z6dC8tntQE3ypp_7Wvm">Forth Haiku youtube playlist</a></p><h1>See Also</h1><p><em>Email</em>: <a href="mailto:ptcomputingsimplicity@gmail.com">ptcomputingsimplicity@gmail.com</a><br><em>Substack</em>: <a href="http://paultarvydas.substack.com/">paultarvydas.substack.com</a><br><em>Videos</em>: <a href="https://www.youtube.com/@programmingsimplicity2980">https://www.youtube.com/@programmingsimplicity2980</a><br><em>Discord</em>: <a href="https://discord.gg/65YZUh6Jpq">https://discord.gg/65YZUh6Jpq</a> <br><em>Leanpub</em>: [WIP] <a href="https://leanpub.com/u/paul-tarvydas">https://leanpub.com/u/paul-tarvydas</a><br><em>Twitter</em>: @paul_tarvydas&lt;br&gt; <em>Bluesky:</em> @paultarvydas.bsky.social&lt;br&gt; <em>Mastodon:</em>@paultarvydas&lt;br&gt; <em>(earlier)</em> <em>Blog:</em> <a href="http://guitarvydas.github.io/">guitarvydas.github.io</a><br><em>References:</em> <a href="https://guitarvydas.github.io/2024/01/06/References.html">https://guitarvydas.github.io/2024/01/06/References.html</a></p><p><em>Paid subscriptions are a voluntary way to support this work.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/p/forth-haiku-compendium/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/p/forth-haiku-compendium/comments"><span>Leave a comment</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/p/forth-haiku-compendium?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/p/forth-haiku-compendium?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/subscribe?"><span>Subscribe now</span></a></p>]]></content:encoded></item><item><title><![CDATA[You Already Know PBP]]></title><description><![CDATA[2026-05-13]]></description><link>https://programmingsimplicity.substack.com/p/you-already-know-pbp</link><guid isPermaLink="false">https://programmingsimplicity.substack.com/p/you-already-know-pbp</guid><pubDate>Wed, 13 May 2026 21:49:31 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!eSyZ!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d69eba9-d5d3-4387-a046-9b881b00bd45_131x131.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>TL;DR</h2><p>A Unix pipeline is a PBP Container. You just never generalized it.</p><h2>L;R</h2><p>When you write <code>ls | grep foo | wc -l</code>, you are doing something remarkable without thinking about it. Three programs run concurrently. None of them knows what it is connected to. <code>grep</code> does not call <code>wc</code>. It writes to stdout and forgets. The wiring &#8212; who feeds whom &#8212; is declared outside the programs, on the command line, by you.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Programming Simplicity is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>That is PBP. Parts Based Programming.</p><p>Each command in the pipeline is a Part. It has an input port (stdin) and an output port (stdout) and no knowledge of the pipeline it inhabits. The pipeline itself is a Container &#8212; it knows the topology; its Parts do not. A Part can itself be a shell script that contains another pipeline, making it a Container in turn. The hierarchy composes.</p><p>A sequential pipeline is one kind of Container. PBP Containers are more general &#8212; the wiring inside can fan out, loop back, or converge, not just chain. But the Unix pipeline is enough to show you the idea: topology declared externally, components oblivious to their neighbors, communication by message rather than by call.</p><h2>Where Pipes Stop</h2><p>Unix pipes prove the concept but the syntax freezes your thinking. Shell scripts can call other shell scripts. File descriptors can serve as ports. The composition is there if you work at it. But the text syntax nudges you toward chains &#8212; one program feeding the next, left to right &#8212; because that is what the <code>|</code> character expresses naturally. Fan-out, fan-in, and feedback are possible but awkward to write and hard to see.</p><p>PBP uses diagrammatic syntax. Fan-out, feedback, and arbitrary topologies are drawn, not written. The diagram makes the structure visible and natural to think about, not a clever trick you have to construct from text primitives.</p><p>The second difference is what gets passed. Pipes carry bytes. PBP passes mevents &#8212; two-part messages consisting of a tag and an unstructured byte payload. Tag is port name; payload is data. This is a key/value pair, and the key is what makes multiple named input and output ports thinkable. You stop reasoning about a stream and start reasoning about discrete, labelled messages arriving on specific ports. That shift is what lets you break out of the chain-of-processes paradigm entirely.</p><p>The one-input-queue-per-Part rule follows from this. Each Part receives mevents in arrival order on a single queue. Mevent ordering becomes something you can reason about explicitly, rather than something you manage through ad hoc state variables scattered across your code.</p><p>The third difference is weight. Unix pipes are OS-level &#8212; you pay for process creation, scheduling, and kernel context switches. PBP&#8217;s process model is defined simply enough that the entire kernel can be implemented in a small amount of Python. No operating system required.</p><h2>Why Not Just Use CALL/RETURN</h2><p>The reason software does not work this way by default is CALL/RETURN. Functions call functions, wait for results, and return. That model made sense on a single CPU in 1970. It makes less sense when your components are threads, processes, or machines on a network. CALL/RETURN forces synchrony onto a world that is not synchronous.</p><p>Unix got this right in 1973 and then software forgot the lesson.</p><h1>References</h1><ul><li><p><a href="https://www.youtube.com/playlist?list=PLHh2_dCKBPjbBN2R8xwBiS4nHlo5iQjqS">PBP Cookbook</a> beginning with simple Hello World demo and installation of tools and kernel</p></li><li><p><a href="https://github.com/guitarvydas/pbp-dev">PBP tools and kernel development</a> , see <code>kernel/kernel.drawio</code> and <code>kernel/*.rt</code>for kernel sources (use drawio to read/edit kernel.drawio) ; collaborators welcome</p></li></ul><h1>See Also</h1><p><em>Email</em>: <a href="mailto:ptcomputingsimplicity@gmail.com">ptcomputingsimplicity@gmail.com</a> <em>Substack</em>: <a href="http://paultarvydas.substack.com/">paultarvydas.substack.com</a> <em>Videos</em>: <a href="https://www.youtube.com/@programmingsimplicity2980">https://www.youtube.com/@programmingsimplicity2980</a> <em>Discord</em>: <a href="https://discord.gg/65YZUh6Jpq">https://discord.gg/65YZUh6Jpq</a> <em>Leanpub</em>: [WIP] <a href="https://leanpub.com/u/paul-tarvydas">https://leanpub.com/u/paul-tarvydas</a><em>Twitter</em>: @paul_tarvydas <em>Bluesky:</em> @paultarvydas.bsky.social <em>Mastodon:</em> @paultarvydas<em>(earlier)</em> <em>Blog:</em> <a href="http://guitarvydas.github.io/">guitarvydas.github.io</a> <em>References:</em><a href="https://guitarvydas.github.io/2024/01/06/References.html">https://guitarvydas.github.io/2024/01/06/References.html</a></p><p><em>Paid subscriptions are a voluntary way to support this work.</em></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Programming Simplicity is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[The Limits of Mathematical Computation Applied to Physical Hardware]]></title><description><![CDATA[2026-05-03]]></description><link>https://programmingsimplicity.substack.com/p/the-limits-of-mathematical-computation</link><guid isPermaLink="false">https://programmingsimplicity.substack.com/p/the-limits-of-mathematical-computation</guid><dc:creator><![CDATA[Paul Tarvydas]]></dc:creator><pubDate>Sun, 03 May 2026 13:17:06 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!eSyZ!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d69eba9-d5d3-4387-a046-9b881b00bd45_131x131.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>TL;DR</h2><p>Every executable program can be described as a formal language. The converse does not hold. Not every capability of physical hardware can be expressed in a mathematical model of computation. This is a one-way street, and the traffic has been going the wrong way for fifty years.</p><div><hr></div><h2>L;R</h2><h2>The Statement That Feels Obviously True</h2><p>Everything executable by a computer is a formal language. This is true, and it feels complete &#8212; as if it closes the question. If every program is formal, and formal languages are the subject of computer science, then computer science covers everything a computer can do. The logic seems airtight.</p><p>It isn&#8217;t. The statement is a one-way relationship. It says nothing about the converse. The converse &#8212; that every capability of physical hardware can be expressed in a formal, mathematical language &#8212; does not follow, and is false. The word &#8220;formal&#8221; is doing double duty without anyone noticing: assembler is formal in the sense of being precisely specified, but modern programming languages are formal in the sense of being mathematical abstractions independent of physical hardware. Conflating the two meanings makes the one-way street look two-way.</p><h2>Interrupts: The Counterexample That Cannot Be Argued Away</h2><p>An interrupt is a hardware event that stops the CPU at an arbitrary moment &#8212; determined by the outside world, not by the program &#8212; saves machine state, executes a handler, restores state, and resumes. The program did not call anything. There is no caller, no return value, no scheduled moment. The outside world reached into the machine between two instructions and redirected it.</p><p>The immediate objection is: you can write a callback that responds to an interrupt. Yes, you can. But the callback is not the interrupt. A callback is a function, and a function in the mathematical sense is synchronous and side-effect-free by definition. An interrupt handler is neither. It has side effects by definition &#8212; it modifies machine state &#8212; and it fires asynchronously, at a moment the program did not choose and cannot predict. You can bolt a callback onto the interrupt mechanism, but the asynchronous, uninvited, side-effecting hardware event underneath it remains outside the mathematical model.</p><p>Mathematical computation is a closed system. It maps inputs to outputs on its own schedule. An interrupt is the outside world breaking into that schedule uninvited. A closed system has no vocabulary for this. You can simulate it &#8212; polling, cooperative yielding, continuation-passing &#8212; but simulation changes what is being modeled. Polling is not an interrupt. It is the program asking, at moments of its own choosing, whether something happened. An interrupt does not ask permission.</p><h2>Where the Trade Was Made</h2><p>The assembler-to-C transition is where the physical model was quietly replaced by the mathematical one. Assembler is the machine&#8217;s own notation: every instruction directly specifies a physical state change, including interrupt vectors, privileged operations, and cycle-exact timing. C replaced this with a mathematical abstraction: functions, typed values, a memory model, a calling convention. The abstraction is useful &#8212; it raised the floor enormously. But it lowered the ceiling. Capabilities that were native and direct in assembler became impossible or required operating system mediation in C.</p><p>Every language since &#8212; C++, Java, Python, Haskell, Rust &#8212; has refined the mathematical model. None has gone back to recover what was traded away at the assembler-to-C boundary. The industry has spent fifty years polishing an abstraction that is categorically mismatched with the physical hardware it runs on, and has celebrated the polish as progress.</p><p>The mismatch does not matter for batch computation: sort this list, compute this hash, prove this theorem. The machine waits. But for real-time systems, distributed networks, interrupt-driven hardware, and any system embedded in a world that keeps happening on its own schedule &#8212; the mathematical model is not an approximation of the physical reality. It is a different thing entirely, and no amount of additional mathematical machinery brings it closer. The machinery is inside the closed system. The interrupt comes from outside.</p><p><strong>See Also</strong></p><p><em>Email</em>: <a href="mailto:ptcomputingsimplicity@gmail.com">ptcomputingsimplicity@gmail.com</a></p><p><em>Substack</em>: <a href="http://paultarvydas.substack.com">paultarvydas.substack.com</a></p><p><em>Videos</em>: <a href="https://www.youtube.com/@programmingsimplicity2980">https://www.youtube.com/@programmingsimplicity2980</a></p><p><em>Discord</em>: <a href="https://discord.gg/65YZUh6Jpq">https://discord.gg/65YZUh6Jpq</a></p><p><em>Leanpub</em>: [WIP] <a href="https://leanpub.com/u/paul-tarvydas">https://leanpub.com/u/paul-tarvydas</a></p><p><em>Twitter</em>: @paul_tarvydas</p><p><em>Bluesky:</em> @paultarvydas.bsky.social</p><p><em>Mastodon: </em>@paultarvydas</p><p><em>(earlier)</em> <em>Blog:</em> <a href="http://guitarvydas.github.io">guitarvydas.github.io</a></p><p><em>References:</em> <a href="https://guitarvydas.github.io/2024/01/06/References.html">https://guitarvydas.github.io/2024/01/06/References.html</a></p><p><em>Paid subscriptions are a voluntary way to support this work.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/p/the-limits-of-mathematical-computation/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/p/the-limits-of-mathematical-computation/comments"><span>Leave a comment</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/p/the-limits-of-mathematical-computation?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/p/the-limits-of-mathematical-computation?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/subscribe?"><span>Subscribe now</span></a></p><p></p>]]></content:encoded></item><item><title><![CDATA[From State Machine Diagram to Python]]></title><description><![CDATA[2026-05-03]]></description><link>https://programmingsimplicity.substack.com/p/from-state-machine-diagram-to-python</link><guid isPermaLink="false">https://programmingsimplicity.substack.com/p/from-state-machine-diagram-to-python</guid><dc:creator><![CDATA[Paul Tarvydas]]></dc:creator><pubDate>Sun, 03 May 2026 12:08:05 GMT</pubDate><enclosure url="https://api.substack.com/feed/podcast/196304529/3075fd8dafc2d30493c5e38b6c0a2864.mp3" length="0" type="audio/mpeg"/><content:encoded><![CDATA[<p>I walk through a simple three-state state machine with an idle state and two &#8220;wait for recrossing&#8221; states, showing how transitions fire based on guards like x &#65310; max or x &#65308; min (with e encapsulating environment values such as x, max, min).</p><p>I demonstrate converting the diagram into a textual intermediate representation called SM and then generating equivalent Python code with enter, step, and exit sections per state.</p><p>I explain how each event triggers transition tests, runs transition code (e.g., e.reverse), exits the current state, and enters the next state, or otherwise falls through to remain in the current state.</p><p>I note that the idle state has two mutually exclusive transitions. I want to enforce that only one fires by adding returns after a transition. To accomplish this, I update the T2T rewrite rules in sm-metapy.rwr to insert returns in generated code.</p><p>I note that the Python is not optimized but aims to stay true to the diagram, and mention experimental, not-yet-debugged work applying these drawings to a collision detector for the PBP Pong project.</p><p>00:00 Three State Overview<br>00:58 Dot SM Text Format<br>01:35 States Enter Step Exit<br>02:39 Guards And Transitions<br>03:18 Generated Python Code<br>04:22 Ensuring Single Transition<br>05:11 Updating The Code Emitter<br>06:02 Results And Next Steps</p><p>code repository: <a href="https://github.com/guitarvydas/sm-pbp">https://github.com/guitarvydas/sm-pbp</a></p><p><strong>See Also</strong></p><p><em>Email</em>: <a href="mailto:ptcomputingsimplicity@gmail.com">ptcomputingsimplicity@gmail.com</a></p><p><em>Substack</em>: <a href="http://paultarvydas.substack.com">paultarvydas.substack.com</a></p><p><em>Videos</em>: <a href="https://www.youtube.com/@programmingsimplicity2980">https://www.youtube.com/@programmingsimplicity2980</a></p><p><em>Discord</em>: <a href="https://discord.gg/65YZUh6Jpq">https://discord.gg/65YZUh6Jpq</a></p><p><em>Leanpub</em>: [WIP] <a href="https://leanpub.com/u/paul-tarvydas">https://leanpub.com/u/paul-tarvydas</a></p><p><em>Twitter</em>: @paul_tarvydas</p><p><em>Bluesky:</em> @paultarvydas.bsky.social</p><p><em>Mastodon: </em>@paultarvydas</p><p><em>(earlier)</em> <em>Blog:</em> <a href="http://guitarvydas.github.io">guitarvydas.github.io</a></p><p><em>References:</em> <a href="https://guitarvydas.github.io/2024/01/06/References.html">https://guitarvydas.github.io/2024/01/06/References.html</a></p><p><em>Paid subscriptions are a voluntary way to support this work.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/subscribe?"><span>Subscribe now</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/p/from-state-machine-diagram-to-python?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/p/from-state-machine-diagram-to-python?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/p/from-state-machine-diagram-to-python/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/p/from-state-machine-diagram-to-python/comments"><span>Leave a comment</span></a></p><p></p>]]></content:encoded></item><item><title><![CDATA[Source Code Control Doesn’t Need to Store Source Code]]></title><description><![CDATA[2026-04-26]]></description><link>https://programmingsimplicity.substack.com/p/source-code-control-doesnt-need-to</link><guid isPermaLink="false">https://programmingsimplicity.substack.com/p/source-code-control-doesnt-need-to</guid><dc:creator><![CDATA[Paul Tarvydas]]></dc:creator><pubDate>Sun, 26 Apr 2026 13:37:06 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!eSyZ!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d69eba9-d5d3-4387-a046-9b881b00bd45_131x131.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div><hr></div><p><strong>TL;DR &#8212; Source code control only needs to store enough syntactic and semantic information to reconstruct human-readable form on checkout. We assumed otherwise because 20th-century CPUs were too slow to make transformation practical. That assumption is now obsolete.</strong></p><div><hr></div><p>L;R</p><h2>The Assumption We Never Questioned</h2><p>Source code control systems store text files. That&#8217;s the unexamined assumption baked into every tool from SCCS to Git. The text file is treated as the ground truth. What you check in is what gets stored. What gets stored is what you check out.</p><p>This assumption was born of necessity. In the 20th century, CPU cycles were expensive. Spending them on tooling was a luxury most shops couldn&#8217;t afford. So we stored source &#8220;as is&#8221; &#8212; static, human-readable, character-for-character identical on the way in and out.</p><p>That constraint no longer exists. We haven&#8217;t updated our tools to reflect that.</p><h2>What Source Code Control Actually Needs to Do</h2><p>Source code control has one job: preserve enough syntactic and semantic information to reconstruct the source faithfully.</p><p>It does not need to preserve the exact text representation. It needs to preserve the <em>meaning</em> and <em>structure</em>. The human-readable form is a <em>rendering</em> of that structure &#8212; not the structure itself.</p><p>This is the insight behind projectional editing. A projectional editor stores an AST or semantic graph, then renders it into whatever human-readable form is appropriate for the current task. The stored form and the displayed form are decoupled.</p><p>Source code control can work the same way. Check-in applies a transformation: source text &#8594; normalized machine-readable form. Checkout applies the inverse: machine-readable form &#8594; source text (or any other rendering).</p><h2>Lisp Pointed at This Decades Ago</h2><p>Lisp is worth examining here. A Lisp program is already close to its own AST. Everything normalizes down to either a function application or an atomic object. The s-expression syntax is a nearly direct serialization of the semantic tree.</p><p>This is why Lisp macros are powerful: the code <em>is</em> the data structure. Transformations over code are just transformations over lists.</p><p>Lisp didn&#8217;t go far enough &#8212; it still stores and transmits s-expressions as text &#8212; but it identified the right level of abstraction. The canonical form should be the semantic structure, not a particular textual rendering of it.</p><h2>Factbases: Flatter Than Lisp</h2><p>Lisp normalizes to a recursive structure. There is a deeper normalization.</p><p>The triple: </p><p><code>relation(subject, object)</code>.</p><p>This fragments meaning into atomic elements that carry no embedded structure. The elements can appear in any order. No element points to another in the low-level sense. A subject is an identifier &#8212; a name. An object is an identifier. Neither is a hard-coded address. Neither encodes position. A reference in a factbase is an indirection, not a pointer.</p><p>Prolog works with this representation. Prolog expends CPU cycles to infer structure from it.</p><p>Consider encoding the fact that variable <code>x</code> is an integer with value <code>42</code>:</p><pre><code><code>type(x, int).
value(x, 42).</code></code></pre><p>This is identical in meaning to:</p><pre><code><code>value(x, 42).
type(x, int).</code></code></pre><p>Order doesn&#8217;t matter. There are no pointers. There is no tree to traverse. There is only a set of atomic facts and an inference engine that can assemble them into whatever structure a query demands.</p><p>From those two facts, inference can reconstruct:</p><pre><code><code>var x: int = 42</code></code></pre><p>The concise, human-readable form is <em>derived</em>, not stored. The stored form is the flat factbase. The readable form is a rendering.</p><p>This is exactly the pattern a source code control system could exploit. Store the factbase. Render on checkout. The rendering is a query over the facts &#8212; a transformation, not a retrieval.</p><h2>What Factbases Buy Over Lisp</h2><p>Lisp&#8217;s s-expressions preserve tree structure. The parent-child relationship is encoded in nesting. To change the structure, you change the nesting.</p><p>A factbase has no nesting. Structure is inferred, not stored. This means:</p><ul><li><p>Adding a new relation to an existing subject requires no restructuring. You append a fact.</p></li><li><p>Querying across subjects requires no pointer traversal. You pattern-match.</p></li><li><p>Diffing two factbases is a set operation &#8212; which facts were added, which removed &#8212; not a tree diff.</p></li></ul><p>There is a further practical consequence. Because facts are order-independent, a factbase can be stored in sorted form. Sorting does not scramble the semantic information &#8212; any ordering retains the full semantics. But a canonically sorted factbase is far more amenable to existing diff and git tooling than raw source text. Two versions of a program that differ in one relation will produce a clean, minimal diff over their sorted factbases. The same change in source text might produce a noisy diff spanning multiple lines, or no diff at all if the change was a refactor that preserved textual structure while altering meaning. Sorting is free. The improvement to diff quality is not.</p><p>This means the proposal does not require replacing git. Git can remain exactly as it is. What changes is what git is given to store. Feed git a canonically sorted factbase instead of raw source text, and git&#8217;s existing diff, merge, and history machinery works better than it ever did on source. The transformation happens at the boundary &#8212; on check-in and checkout &#8212; and git operates on the normalized form without needing to know anything changed.</p><p>A semantic diff of two versions of a program becomes: what facts changed? Not: what characters changed. Not even: what AST nodes changed. What <em>relations</em> changed.</p><p>That is a diff at the level of meaning.</p><h2>The CPU Trade</h2><p>Prolog infers. Inference costs CPU cycles.</p><p>In 1980, this cost was prohibitive for routine tooling. Today it is not. A factbase representing a large codebase is still a small dataset by modern standards. The inference required to reconstruct human-readable form from a factbase is well within what current hardware makes trivial.</p><p>We are not proposing anything computationally exotic. We are proposing that tools run a Prolog query on checkout instead of copying bytes.</p><h2>Inferencing Is Not Prolog-Specific</h2><p>Prolog is a convenient syntax for expressing inferencing. It is not the only way to do it.</p><p>Nils Holm wrote a complete Prolog inferencer in Scheme and explained it in approximately six slides worth of code &#8212; &#8220;Prolog Control in Six Slides&#8221; (<a href="https://www.t3x.org/prolog6/">https://www.t3x.org/prolog6/</a>). The point is not the language. The point is the size: a working inferencer consists of a small amount of code.</p><p>I ported Holm&#8217;s inferencer manually to Common Lisp (<a href="https://github.com/guitarvydas/cl-holm-prolog">https://github.com/guitarvydas/cl-holm-prolog</a>) and again to Javascript using OhmJS (<a href="https://github.com/guitarvydas/js-prolog">https://github.com/guitarvydas/js-prolog</a>). The Javascript port includes a diary of the porting process. These ports exist not to produce production inference engines but to demonstrate that the mechanism is simple enough to carry across languages by hand.</p><p>An inferencer can be written in any language. Prolog syntax is convenient &#8212; relations expressed as <code>relation(subject, object)</code> read naturally and the unification semantics are clean &#8212; but the syntax is separable from the mechanism. If Prolog syntax is an obstacle, replace it. The inferencing still works.</p><h2>MiniKanren: A Different Trade</h2><p>MiniKanren (<a href="http://minikanren.org/">minikanren.org</a>) is a family of inference systems that make a different computational trade than Prolog.</p><p>Prolog expends CPU cycles for backtracking &#8212; it searches a space of possible solutions by trying, failing, and retrying. MiniKanren avoids backtracking by expending space instead. It represents the search space explicitly and explores it without the overhead of backtrack-and-retry.</p><p>Both achieve inferencing. They make different trade-offs between CPU and memory. In the context of source code control &#8212; where the factbases are relatively small and queries run at checkout time, not in inner loops &#8212; the trade-off is largely academic. Either approach works.</p><p>The practical point is: inferencing is a solved problem, it is small enough to port by hand, and the implementation language does not matter. A source code control system that stores factbases and runs inference on checkout is not proposing exotic machinery. It is proposing ordinary programming with a different data model.</p><h2>Transformations on the Way In and Out</h2><p>There is no rule that says a version control system must store source verbatim.</p><p>A VCS can apply a transformation pipeline on check-in: parse the source, extract the semantic structure, store a normalized form. On checkout, the inverse pipeline runs: take the normalized form, render it into whatever human-readable shape the developer needs.</p><p>Those two shapes need not be identical. A junior developer might get a more verbose, annotated rendering. A senior developer might get a compact, dense form. A code reviewer might get a diff at the semantic level rather than the text level &#8212; showing what <em>changed</em> structurally, not just what characters differ.</p><p>None of this requires storing anything extra. It just requires running a transformation on checkout.</p><h2>Why We Didn&#8217;t Think This Way</h2><p>CPU cycles were the constraint. In 1975, spending processor time on pretty-printing or semantic reconstruction at checkout was unacceptable overhead. Tools had to be fast. Fast meant: don&#8217;t transform, just copy bytes.</p><p>That decision calcified into assumption. The assumption calcified into convention. The convention calcified into &#8220;the way source control works.&#8221;</p><p>We designed around a bottleneck that no longer exists.</p><h2>What Becomes Possible</h2><p>Once check-in and checkout are transformation boundaries, several things open up:</p><p><em>Semantic diffing.</em> Compare ASTs or factbases, not character streams. Detect that a function was renamed even if it moved to a different file. Know which <em>relations</em> changed, not which lines changed.</p><p><em>Multiple renderings of the same codebase.</em> One stored form, many views. Render for documentation, for review, for onboarding, for debugging &#8212; each optimized for its purpose.</p><p><em>Notation independence.</em> Store the semantic graph or factbase. Render into Python syntax, or Lisp syntax, or a diagram, or a table. The notation becomes a view over the model, not the model itself.</p><p><em>Programmatic normalization.</em> Formatting debates disappear. The canonical form is the semantic structure. Human-readable renderings are generated, not hand-maintained.</p><h2>The Deeper Point</h2><p>We built 20th-century tools under 20th-century constraints. We then treated those tools as definitions of what source code control <em>is</em>, rather than as solutions to problems that no longer exist in the same form.</p><p>Source code control is not &#8220;store text files and track diffs.&#8221; That&#8217;s an implementation that made sense under specific historical conditions.</p><p>Source code control is &#8220;preserve enough information to reconstruct the program.&#8221; How we store that information, and what form we present it in, are engineering choices &#8212; not axioms.</p><p>The computers are fast enough now. The question is whether we&#8217;re willing to rethink the tools.</p><div><hr></div><h2>Appendix: Working SWI-Prolog Code</h2><p>Three files. The inference code is <code>render.pl</code>. The factbases are separate.</p><p><strong>render.pl</strong></p><pre><code><code>render(Var, Result) :-
    type(Var, Type),
    value(Var, Val),
    format(atom(Result), 'var ~w : ~w = ~w', [Var, Type, Val]).

render_all :-
    forall(type(Var, _), (render(Var, R), writeln(R))).</code></code></pre><p><strong>facts1.pl &#8212; sorted</strong></p><pre><code><code>:- discontiguous type/2, value/2.
type(x, int).
type(y, float).
value(x, 42).
value(y, 99).</code></code></pre><p><strong>facts2.pl &#8212; reverse-sorted</strong></p><pre><code><code>:- discontiguous type/2, value/2.
value(y, 99).
value(x, 42).
type(y, float).
type(x, int).</code></code></pre><p>Run either factbase against the same inference code:</p><pre><code><code>swipl -q -g "render_all, halt" facts1.pl render.pl
swipl -q -g "render_all, halt" facts2.pl render.pl</code></code></pre><p>Output from <code>facts1.pl</code>:</p><pre><code><code>var x : int = 42
var y : float = 99</code></code></pre><p>Output from <code>facts2.pl</code>:</p><pre><code><code>var y : float = 99
var x : int = 42</code></code></pre><p>The rendered declaration for each variable is identical in both cases. The output order follows the order facts appear in the file &#8212; itself an illustration of the point: a canonically sorted factbase produces a canonically ordered rendering, and a VCS storing that sorted form gets clean, minimal diffs as a direct consequence.</p><p>The <code>:- discontiguous</code> declarations tell SWI-Prolog that facts of the same relation may appear non-contiguously &#8212; exactly the condition that holds in a sorted factbase, where facts are ordered globally rather than grouped by relation.</p><p>The key thing visible here: <code>render.pl</code> is six lines. The factbase is data. The inference is code. They are completely decoupled.</p><p><strong>See Also</strong></p><p><em>Email</em>: <a href="mailto:ptcomputingsimplicity@gmail.com">ptcomputingsimplicity@gmail.com</a></p><p><em>Substack</em>: <a href="http://paultarvydas.substack.com">paultarvydas.substack.com</a></p><p><em>Videos</em>: <a href="https://www.youtube.com/@programmingsimplicity2980">https://www.youtube.com/@programmingsimplicity2980</a></p><p><em>Discord</em>: <a href="https://discord.gg/65YZUh6Jpq">https://discord.gg/65YZUh6Jpq</a></p><p><em>Leanpub</em>: [WIP] <a href="https://leanpub.com/u/paul-tarvydas">https://leanpub.com/u/paul-tarvydas</a></p><p><em>Twitter</em>: @paul_tarvydas</p><p><em>Bluesky:</em> @paultarvydas.bsky.social</p><p><em>Mastodon: </em>@paultarvydas</p><p><em>(earlier)</em> <em>Blog:</em> <a href="http://guitarvydas.github.io">guitarvydas.github.io</a></p><p><em>References:</em> <a href="https://guitarvydas.github.io/2024/01/06/References.html">https://guitarvydas.github.io/2024/01/06/References.html</a></p><p><em>Paid subscriptions are a voluntary way to support this work.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/p/source-code-control-doesnt-need-to/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/p/source-code-control-doesnt-need-to/comments"><span>Leave a comment</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/p/source-code-control-doesnt-need-to?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/p/source-code-control-doesnt-need-to?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://programmingsimplicity.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://programmingsimplicity.substack.com/subscribe?"><span>Subscribe now</span></a></p>]]></content:encoded></item></channel></rss>