<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" 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"><channel><title>De Programmatica Ipsum</title><link>https://deprogrammaticaipsum.com/</link><description>Recent content on De Programmatica Ipsum</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Mon, 06 Jul 2026 05:03:00 +0200</lastBuildDate><atom:link href="https://deprogrammaticaipsum.com/index.xml" rel="self" type="application/rss+xml"/><item><title>Issue 094: Killer Apps</title><link>https://deprogrammaticaipsum.com/issue-94-killer-apps/</link><pubDate>Mon, 06 Jul 2026 05:03:00 +0200</pubDate><guid>https://deprogrammaticaipsum.com/issue-94-killer-apps/</guid><description><![CDATA[ <p>Welcome to the 94th issue of <em>De Programmatica Ipsum</em>, about <em>Killer Apps</em>.</p>
<p>In this edition:</p>
<ul>
<li>Graham argues that the &ldquo;Killer App&rdquo; phenomenon is <a href="/where-are-the-killer-apps/">in danger of extinction</a>.</li>
<li>Adrian enumerates some examples of <a href="/behold-the-app-killers/">&ldquo;App Killers&rdquo;</a>.</li>
<li>In our <a href="/category/videotheque/">Vidéothèque section</a>, we watch the moment <a href="/dan-bricklin/">Dan Bricklin</a> told his team about the release of the first IBM PC in 1981.</li>
<li>In the <a href="/category/library/">Library section</a>, we review &ldquo;Using ARexx on the Amiga&rdquo; by <a href="/chris-zamara-nick-sullivan/">Chris Zamara &amp; Nick Sullivan</a>.</li>
</ul>
<p>Download this issue in DRM-free <a href="/pdf/issue-094-killer-apps.pdf">PDF</a> or <a href="/epub/issue-094-killer-apps.epub">EPUB</a> format, and read it on your preferred device. You can also subscribe to <a href="/index.xml">our RSS feed</a>, featuring the full content of our articles.</p>]]></description><content:encoded><![CDATA[ <p>Welcome to the 94th issue of <em>De Programmatica Ipsum</em>, about <em>Killer Apps</em>.</p>
<p>In this edition:</p>
<ul>
<li>Graham argues that the &ldquo;Killer App&rdquo; phenomenon is <a href="/where-are-the-killer-apps/">in danger of extinction</a>.</li>
<li>Adrian enumerates some examples of <a href="/behold-the-app-killers/">&ldquo;App Killers&rdquo;</a>.</li>
<li>In our <a href="/category/videotheque/">Vidéothèque section</a>, we watch the moment <a href="/dan-bricklin/">Dan Bricklin</a> told his team about the release of the first IBM PC in 1981.</li>
<li>In the <a href="/category/library/">Library section</a>, we review &ldquo;Using ARexx on the Amiga&rdquo; by <a href="/chris-zamara-nick-sullivan/">Chris Zamara &amp; Nick Sullivan</a>.</li>
</ul>
<p>Download this issue in DRM-free <a href="/pdf/issue-094-killer-apps.pdf">PDF</a> or <a href="/epub/issue-094-killer-apps.epub">EPUB</a> format, and read it on your preferred device. You can also subscribe to <a href="/index.xml">our RSS feed</a>, featuring the full content of our articles.</p>
<p>We would like to thank our patrons who generously contribute every month (or have contributed in the past) to our work and help us run this magazine. Thank you so much! In alphabetical order: Adam Guest, Adrian Tineo Cabello, Benjamin Sheldon, Christopher Nascone, Colin Powell, Franz Lucien Moersdorf, Guillermo Ramos Álvarez, Jean-Paul de Vooght, Dr. Juande Santander-Vela, Patryk Matuszewski, Paul Hudson, Quico Moya, Roger Turner, Szymon Licau, and countless more leaving anonymous tips every month.</p>
<p>Enjoy this issue! Please share our articles on social media, or <a href="/contribute/">contribute</a> if you would like to support our work with a donation via <a href="https://liberapay.com/akosma/donate">Liberapay</a>.</p>
<p>Cover photo by <a href="https://unsplash.com/@joshstyle?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Joshua Coleman</a> on <a href="https://unsplash.com/photos/a-group-of-people-standing-next-to-a-yellow-police-line-g86cBfIbd6E?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a>.</p>
]]></content:encoded></item><item><title>Where Are The Killer Apps?</title><link>https://deprogrammaticaipsum.com/where-are-the-killer-apps/</link><pubDate>Mon, 06 Jul 2026 05:02:02 +0200</pubDate><guid>https://deprogrammaticaipsum.com/where-are-the-killer-apps/</guid><description> &lt;p>I have more experience with situations where apps have already done the killing, than I have with being onboard with a killer app. I never used VisiCalc, for example, joining the spreadsheet revolution long after the field was already overfull with competitors (I certainly used some similar spreadsheet on the Dragon 32, but really got going with MiniOffice on the Amiga). People who ran the UK academic ISP &lt;a href="https://en.wikipedia.org/wiki/JANET">JANET&lt;/a> tell me that the X window system (originally on VMS) was the killer app for the Internet Protocol, and led to their implementing that over the favoured X.25 protocol, but I did not connect a computer to JANET until 2000, long after IPv4 had won out. I did use Deluxe Paint on the Amiga, but long after Andy Warhol had done the same and after other platforms had similar packages.&lt;/p></description><content:encoded><![CDATA[ <p>I have more experience with situations where apps have already done the killing, than I have with being onboard with a killer app. I never used VisiCalc, for example, joining the spreadsheet revolution long after the field was already overfull with competitors (I certainly used some similar spreadsheet on the Dragon 32, but really got going with MiniOffice on the Amiga). People who ran the UK academic ISP <a href="https://en.wikipedia.org/wiki/JANET">JANET</a> tell me that the X window system (originally on VMS) was the killer app for the Internet Protocol, and led to their implementing that over the favoured X.25 protocol, but I did not connect a computer to JANET until 2000, long after IPv4 had won out. I did use Deluxe Paint on the Amiga, but long after Andy Warhol had done the same and after other platforms had similar packages.</p>
<p>Really the only killer app I was in on the ground floor for was the most famously fumbled (though still incredibly successful) killer app in history: Facebook. I was working at Oxford University when Facebook came out, so once they expanded out to campuses beyond Harvard, I was in one of the earlier networks to join up. (You might not remember this from the early days of Facebook, but the site was segregated into separate instances that ran on different &ldquo;networks&rdquo;. A member from Harvard would see their Harvard friends, but nobody from MIT.) It turned out that Facebook was the killer app for university computer rooms, and before too long over a quarter of all email handled by the university&rsquo;s central mail service was Facebook notifications, reminding people like me that that one Philosophy student I met in the pub once and decided to add to Facebook had poked me.</p>
<p>Where is the fumble? Well it turns out that Facebook was the killer app for mobile computing, and everybody noticed it except Facebook. It turns out that when you are super-rich, that kind of mistake is not existential—think Microsoft missing out on the early years of the public Internet, or Metallica opting out of music streaming—it is just embarrassing, and costs you quite a lot of that vast pile of money to catch up. In the early days of Facebook, it was conceived as a live status blog, in the style of the old <a href="https://en.wikipedia.org/wiki/Finger_(protocol)">&ldquo;finger&rdquo; protocol</a> on UNIX. The placeholder text for my &ldquo;wall&rdquo; (the place in my profile for public posts) prompted &ldquo;Graham is…&rdquo;, and I would describe what I am doing in a way that made people believe that I had an interesting life, and was not the kind of person who sat in the computer room writing status updates on the web.</p>
<p>Mobile computing—once the ridiculously poor performance of GPRS was a thing of the past, the abysmal capabilities of WAP were transcended, and service providers stopped charging ridiculous figures for a few kilobytes of HTML—offered a new reality, one in which one could explain what &ldquo;Graham is…&rdquo; doing <em>while Graham is doing it</em>. Twttr/Twitter noticed this in 2006. Burbn/Instagram noticed in 2010. Meanwhile, in 2010, only 150 million of Facebook&rsquo;s 500 million users accessed the site via mobile. Why? Facebook had been in at the start with the Facebook mobile app for iPhoneOS/iOS, frequently the number one downloaded app. But it was not a focus; one person (<a href="https://en.wikipedia.org/wiki/Joe_Hewitt_(programmer)">Joe Hewitt</a>) created the app and in true Facebook fashion, really open source a whole app framework (<a href="https://web.archive.org/web/20090324235223/http://joehewitt.com/post/the-three20-project/">Three20</a>) that supported development of that single app. When Hewitt left the company in 2009, they needed to take a very different approach. Eventually they just bought Instagram and pretended they were cool all along.</p>
<p>A killer app sits in a precarious situation. It is an app that is so popular, it changes the value proposition of the platform it runs on; people went out and bought Apple ][ computers just so they could run VisiCalc. Musicians bought Acorn Archimedes so that they could run Sibelius. That is a problem for everybody involved. It is a problem for the makers of the killer app, because their platform vendor is not shifting enough kit for them to sell their software to all their customers. It is a problem for the platform vendor, because now they are not in control of the marketing for their product. The people who make the killer app want to port to different platforms, to satisfy latent demand. That is why you can get Sibelius for PC these days, and why Deluxe Paint was available for MS-DOS, Apple ][GS, and Atari ST. The people who make the platform want to diversify beyond the app&rsquo;s customers, to regain control of the platform. That is why the marketing for the Mac is not all about how it is the latest thing from the people who gave you the opportunity to run VisiCalc. The people who make other apps want to make clones of the killer app, because it shows where the demand is. That is why you have used Excel, and you have not used VisiCalc. And the people who make other platforms want someone to make a clone of the killer app, so that customers choose their platform over the one with the killer app. That is the reason that IBM PC-compatible computers were briefly better marketed as &ldquo;Lotus 1-2-3 compatible&rdquo;; it showed that you could run the not-VisiCalc on the not-Apple ][.</p>
<p>The value proposition for software is entirely different in the 2020s than it was in the 20th century. Where Sibelius used to cost £795 to run on the £799 Acorn Archimedes, now you use the free software product MuseScore and do not (have to) pay anything; or you pay under half the previous, one-off price for a lifetime subscription to all future Sibelius releases (same number of currency units, but three decades of inflation later). Other than some die hards who believe in an innate superiority of native applications or of their favoured platform, you will not find much software that is not available for every popular desktop and mobile platform, either via the web or via web-like portable runtimes. No new killer app is going to arrive for any of these platforms, or for an upstart in those fields.</p>
<p>Why did the financial landscape change? Because the platform vendors could not afford to let a killer app take control of their marketing and sales pipelines. App stores exist so that the platform vendors get to choose what software gets sold, what price points and business models are available, and how the software gets described and marketed. No longer does a businessman walk into a computer store and ask for VisiCalc along with whatever box they need to make VisiCalc work; now they have to choose their general-purpose computer and then visit its souk to work out what they are allowed to do with it. Further, the platform vendors get to see what is doing well, and tailor their marketing appropriately—or build their own competing implementation.</p>
<p>Even if an app could break out of that restriction and build an identity that outshines its host platform, there is just no &ldquo;moat&rdquo; that defends any one platform from all of its competitors providing the same facilities. It used to be the case that switching computers was a huge deal: none of the software was compatible, none of the file formats were interchangeable, probably a floppy disk you formatted on one type of computer would not even get recognised on a different machine, even if it physically fit in the drive. That was not just true between manufacturers, but from different computers produced by the same company, too: try to run your Commodore VIC-20 software on a Commodore 64, Plus/4, CBM-II, or Amiga 1000. That is no longer true. All platforms have a web browser, meaning the unholy triumvirate of HTML5, CSS3, and JS is the ultimate portable runtime. A software company no longer has to choose a platform vendor and hope they can keep up with demand; they can reach everyone, whatever they run.</p>
<p>Might we get a killer app from the free software world? it is unlikely. When That is happened before, it is been in the narrow (but previously very lucrative) world of software for IT professionals: think GCC, LAMP stack, or Docker, it is pulled the rug out from under the proprietary alternatives, and the pricing floor with it, but has not led to people specifically buying into platforms <em>because</em> That is how you get to run GCC, LAMP stack, or Docker. Indeed it is one of the features of free software that you can modify the software to suit your needs, so if you are on Windows and you want the benefits of all of that free software, you port it. There used to be a whole company, Cygnus (Cygnus: Your GNU Support, now part of Red Hat, an IBM®™© brand), who did just that. Yes, you can buy a computer from System76 or the Raspberry Pi Foundation specifically because it runs Linux, but I am fine with Asahi on my Mac, my neighbour is fine using the Windows Subsystem for Linux, and my housemate just runs Audacity in Windows 11 on their NUC without questioning the value of their kernel. Free software does not have a moat by design, its purpose is to drain other platforms&rsquo; moats.</p>
<p>It is more likely that future killer apps will demonstrate the value of a new computing paradigm, and set up one of the platform vendors in that paradigm to be the largest supplier, for the couple of weeks it takes Claude Code to clone equivalent software for their competitors. There are precious few emerging paradigms though. You cannot count the &ldquo;AI pin&rdquo;/voice computing paradigm, because you can already do that on things that also have screens, so any compelling voice interaction software is already doable on mobile, desktop, web, and everywhere else. Besides, there are whole generations of humanity who are uncomfortable even having their phone ringer unmuted, who will not walk around talking to a computer like it is <a href="https://en.wikipedia.org/wiki/Majel_Barrett">Majel Barrett Roddenberry</a> standing behind the camera. Similarly, the whole LLM paradigm changes a lot of games, but not in any way that is exclusive to a single provider; whatever you do with Copilot, anyone else can do with an open weights Qwen model on their own computer (just maybe a little slower). Briefly, MoltBot/OpenClaw looked like being a killer app… but killing what, precisely? People bought Mac Minis, gaming laptops, workstations, they ran with Claude, ChatGPT, Gemini, there is no one &ldquo;platform&rdquo; that benefits in the market because of these tools.</p>
<p>Virtual Reality has been just around the corner for about as long as fusion power generation, and as much as it is found meaningful applications in many fields, still has not demonstrated the breakout utility that leads people in the mainstream to buy a headset just so that they can use that one, killer app. Similarly, augmented and mixed reality have even got real electronics that you have actually heard of selling consumer hardware, just not in meaningful quantities. As with VR, nobody has made a killer AR/MR app that makes people buy the hardware to use the software (if you are looking for app ideas, may I suggest a DuoLingo for sign language that tracks your hand movements, or an app for people with <a href="https://en.wikipedia.org/wiki/Prosopagnosia">prosopagnosia</a> that adds virtual &ldquo;Hello, my name is&rdquo; badges to people in contacts?).</p>
<p>Blockchain remains niche (and, for many, confusing: do I need to use a different currency just to run this software?), quantum computing is a mechanism rather than an interaction paradigm, so I think the only other direction from which we might see a killer app any time soon is the one that is furthest from the mainstream: smart dust. I just hope I did not use the phrase &ldquo;killer app&rdquo; in a hauntingly incorrect sense, there.</p>
<p>Cover photo by <a href="https://unsplash.com/@museumsvictoria?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Museums Victoria</a> on <a href="https://unsplash.com/photos/gray-aplle-ii-with-bag-ZJ5h8KoKnY0?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a>.</p>
]]></content:encoded></item><item><title>Behold! The App Killers</title><link>https://deprogrammaticaipsum.com/behold-the-app-killers/</link><pubDate>Mon, 06 Jul 2026 05:02:01 +0200</pubDate><guid>https://deprogrammaticaipsum.com/behold-the-app-killers/</guid><description><![CDATA[ <p>The name &ldquo;Killer App&rdquo; says a lot about the level of violence in the world of business (well, in the world in general). Such a piece of software is dubbed a &ldquo;killer&rdquo; if it somehow triggers a massive uptick in the adoption of its underlying platform, at such levels that would be otherwise impossible to imagine without the app leading the charge. The scale and sheer levels of capital injected into the software industry in the past 50 years have brought quite a few examples of such &ldquo;Killer Apps.&rdquo; But what about the &ldquo;App Killer,&rdquo; that is, those with the opposite effect? Well, it turns out there are quite a few examples of them, too.</p>]]></description><content:encoded><![CDATA[ <p>The name &ldquo;Killer App&rdquo; says a lot about the level of violence in the world of business (well, in the world in general). Such a piece of software is dubbed a &ldquo;killer&rdquo; if it somehow triggers a massive uptick in the adoption of its underlying platform, at such levels that would be otherwise impossible to imagine without the app leading the charge. The scale and sheer levels of capital injected into the software industry in the past 50 years have brought quite a few examples of such &ldquo;Killer Apps.&rdquo; But what about the &ldquo;App Killer,&rdquo; that is, those with the opposite effect? Well, it turns out there are quite a few examples of them, too.</p>
<p>Let us first enumerate some canonical examples of &ldquo;Killer Apps.&rdquo; There is a quintessential one everyone (well, at least computer history boffins like the authors of this journal) mentions: VisiCalc for the Apple II. But there are others; unfortunately for VisiCalc, it was not the actual killer app for the IBM 5150 (aka &ldquo;IBM PC&rdquo;), because Lotus 1-2-3 took that crown.</p>
<p>In the same category, we can also mention Microsoft Office (and by extension, Excel) for Microsoft Windows, one of those few examples where the same company delivered the platform <em>and</em> the software everybody wanted to run at the same time (which also strongly suggests that spreadsheets did have an oversized influence on shopping decisions back in the day!). In a similar vein, <a href="https://en.wikipedia.org/wiki/Aldus_PageMaker">Aldus PageMaker</a> was the killer app for the original Apple Macintosh and the LaserWriter printer, allowing small shops to be able to produce extremely high-quality printouts from their work in a very affordable package (well, at least for businesses).</p>
<p>Other famous examples of &ldquo;Killer Apps&rdquo; would be the Unix operating system for the C programming language; in the 1980s everyone wanted to run (or copy or clone or rewrite) Unix, and said passion pushed its associated programming language to unforeseen levels of popularity (still enjoyed to the time of this publication, by the way). More examples in the programming language arena? I could mention Jupyter and NumPy for Python and even the original iPhone for Objective-C.</p>
<p>In the recently published book <a href="https://geoffreycain.net/steve-jobs-in-exile/">&ldquo;Steve Jobs in Exile,&rdquo;</a> we can read the story of how <a href="https://en.wikipedia.org/wiki/Jean-Marie_Hullot">Jean-Marie Hullot</a>&rsquo;s <a href="https://en.wikipedia.org/wiki/Interface_Builder">Interface Builder</a> was the &ldquo;Killer App&rdquo; for the NeXT computer, used by companies in the financial industry and government to build new applications <a href="/steve-jobs/">in record times</a>.</p>
<p>There is another interesting example I can relate very directly to. In 2008, an otherwise unknown software developer from Switzerland reverse-engineered the API of the national railway company website. He subsequently released a very early application for the iPhone that allowed users to be able to know when the next train was leaving town. That application was <em>not</em> made with the consent of the SBB-CFF-FFS (that is the name of the Swiss national railway company, with a triple acronym in each of the major national languages of the country). After some legal hurdles and reaching an agreement, said developer sold the source code of the app to the SBB-CFF-FFS, who took over its development. The interesting thing is that the mere existence of this application boosted iPhone sales to incredible levels, making Switzerland the country with the highest concentration of iPhones in the world until around 2011.</p>
<p>Closer to us, one could argue that <a href="https://argo-cd.readthedocs.io/en/stable/">Argo CD</a> is the &ldquo;Killer App&rdquo; for Kubernetes; in the experience of this author, the Argo CD console has become, in various DevOps shops, the default dashboard to monitor and deploy countless applications hundreds of times per day, pushing the &ldquo;GitOps&rdquo; paradigm to its pinnacle. I have this small theory of mine that companies install Kubernetes (or their associated products) just for the sake of being able to use Argo CD. And no, I am not kidding, and so far, I have had no facts countering this hypothesis.</p>
<p>But enough of &ldquo;Killer Apps&rdquo;; let us talk about &ldquo;App Killer&rdquo; now. On many occasions, the software industry witnessed an application obliterating a previous one into oblivion, and the factors that cause this destruction are seldom related to the inherent quality of the incumbent or the competitor.</p>
<p>Occasionally the &ldquo;App Killer&rdquo; is just bad business acumen; the <a href="https://en.wikipedia.org/wiki/Osborne_effect">Osborne effect</a>, whereby a company drives itself out of business by announcing a better product than the one it is currently selling… before it is available, thereby cannibalizing its demand and cutting short its supply of cash. <em>Ouch</em>. On the other extreme, we have self-cannibalization, something that Apple practiced with <em>gusto</em> during the legendary run of the 2000s; the iPhone, very famously, destroyed the iPod, with both (very profitable) cash flows directed towards the same bank account. Talk about learning a lesson or two from Osborne.</p>
<p>Speaking about the iPhone, we can say that it was the &ldquo;App Killer&rdquo; for a few other platforms: Symbian, BlackBerry, and even Adobe Flash. Regarding this last case, it is quite ironic that 15 years later, iPhones (and pretty much any device with a relatively modern web browser) can run Adobe Flash content thanks to WebAssembly and <a href="https://ruffle.rs/">Ruffle</a>.</p>
<p>Another business-related &ldquo;App Killer&rdquo; is bad product management. In this respect we can mention Google, which has a long-held tradition of killing products, even relatively successful ones, with short notice and usually without any kind of reasonable upgrade path. There is even a website called <a href="https://killedbygoogle.com/">&ldquo;Killed by Google&rdquo;</a> that keeps track of this (very) long list of casualties. <em>Requiescat in pace, Google Reader</em>. Another interesting case of killing product management skills is that of Facebook obliterating Parse. Mobile app developers old enough to remember this will rejoice. Another recent example? The Humane AI Pin, which effectively obliterated a whole company <a href="https://en.wikipedia.org/wiki/Humane_Inc.">out of business</a>.</p>
<p>Actually, here comes another fascinating &ldquo;App Killer,&rdquo; very <em>en vogue</em> at the time of this publication: Artificial Intelligence, at least the LLM-fueled one, getting massive amounts of <a href="https://brockovichdatacenter.com/">Erin Brockovich</a>-fueled backlash from pretty much everyone except tech bros.</p>
<p>Corporate incompetence is another &ldquo;App Killer&rdquo; related to the previous examples: we have <a href="/a-roller-coaster-of-emotions/">mentioned</a> Borland in the pages of this magazine, erasing itself out of the minds of developers for apparently no rational reason. Oracle does this regularly too, throwing lawyers at pretty much anyone or anything standing in its way, but with demonstrably higher rates of success than Borland. Oh, and speaking of legal issues, let us not forget that lawyers were the &ldquo;App Killers&rdquo; for Napster, too.</p>
<p>Let us not forget about another classical &ldquo;App Killer&rdquo; phenomenon: <a href="https://www.joelonsoftware.com/2000/04/06/things-you-should-never-do-part-i/">major rewrites</a>. Ah yes, a company decides to rewrite their flagship cash cow, only to discover that it was a gargantuan task, it will never be ready on time, and if delivered, it would be immediately replaced by something better? Comes to mind Lotus 1-2-3 Release 3, Digg v4, AngularJS, KDE 4, Windows Longhorn, Evernote 10, Project Pyramid (an effort to rewrite Microsoft Word in the 1990s, eventually abandoned), the 2024 Sonos app overhaul catastrophe, and the canonical example of them all, the rewrite of Netscape Navigator that would lead to Mozilla Firefox… 6 years later, and conceding the web to Internet Explorer.</p>
<p>All things considered, software remains a brittle thing, not because of the pervasiveness of bugs, but because software markets are extremely sensitive to hiccups of all kinds. The application, actually the whole software stack you are using today, has more chances of disappearing in the next ten years than remaining alive, let alone relevant at all. Those apps and platforms that survive the killing spree, usually deemed &ldquo;boring&rdquo; by hype-fueled types, are those that pass the test of time and stability and become actual staples of productivity and mental well-being.</p>
<p>In a certain way, it is a mechanism akin to natural selection, but without anything natural in it.</p>
<p>Cover photo by <a href="https://unsplash.com/@nampoh?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Maxim Hopman</a> on <a href="https://unsplash.com/photos/silhouette-of-person-on-window-PEJHULxUHZs?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a>.</p>
]]></content:encoded></item><item><title>Dan Bricklin</title><link>https://deprogrammaticaipsum.com/dan-bricklin/</link><pubDate>Mon, 06 Jul 2026 05:01:01 +0200</pubDate><guid>https://deprogrammaticaipsum.com/dan-bricklin/</guid><description> &lt;p>Archival footage from the early 1980s has this distinct, almost palpable texture to it. For members of Generation X, it brings memories of Donkey Kong, He-Man, and Star Wars. The colors are slightly washed out, the audio hums with the analog hiss of magnetic tape, and the people on screen seem entirely unaware that they are standing at the edge of technological history. This is particularly true of this month&amp;rsquo;s Vidéothèque entry: there is an added, inescapable layer to the viewing experience: the absolute, crushing weight of dramatic irony. Brace for impact.&lt;/p></description><content:encoded><![CDATA[ <p>Archival footage from the early 1980s has this distinct, almost palpable texture to it. For members of Generation X, it brings memories of Donkey Kong, He-Man, and Star Wars. The colors are slightly washed out, the audio hums with the analog hiss of magnetic tape, and the people on screen seem entirely unaware that they are standing at the edge of technological history. This is particularly true of this month&rsquo;s Vidéothèque entry: there is an added, inescapable layer to the viewing experience: the absolute, crushing weight of dramatic irony. Brace for impact.</p>
<p>In this edition we look back at a <a href="https://www.youtube.com/watch?v=uDsU9wyQ5Ks">staff meeting at Software Arts</a>, held on August 12, 1981, almost precisely 45 years ago. The speaker is Software Arts (not to be mixed with Electronic Arts!) co-founder <a href="https://en.wikipedia.org/wiki/Dan_Bricklin">Dan Bricklin</a>. The full transcript of the staff meeting has been available on Dan Bricklin&rsquo;s personal homepage for the past 24 years at least, as the Internet Archive <a href="https://web.archive.org/web/20020615164901/http://danbricklin.com/ibmpcannouncement1981.htm">dutifully remembers</a>.</p>
<p>The room where the staff met was hot; they complained about the rising temperature right at the beginning, but the heat was nothing compared to the news being delivered. On this precise day, IBM announced its model <a href="https://en.wikipedia.org/wiki/IBM_Personal_Computer">5150</a>, the OG Personal Computer. And Software Arts, the creators of VisiCalc, were holding the &ldquo;Killer App&rdquo; for the IBM PC… or so they thought.</p>
<p>What makes this (otherwise rather boring) video captivating is not merely the juxtaposition of a scrappy hacker culture colliding with the monolithic, suit-and-tie presence of International Business Machines. It is the knowledge of what happens next.</p>
<p>Bricklin reads a letter from IBM addressed to him and his co-founder, <a href="https://en.wikipedia.org/wiki/Bob_Frankston">Bob Frankston</a>. The corporate speak is thick. IBM politely but firmly reminds them of their &ldquo;confidential disclosure&rdquo; agreements, forbidding them from divulging technical specifications beyond what the <a href="https://bocahistory.org/exhibition/ibm-exhibit/">Boca Raton IBM Labs</a> have officially sanctioned. The Software Arts team sits in that stuffy room, looking at photocopied press releases and marveling at the marketing brochures, brimming with the pride of having the unquestioned &ldquo;killer application&rdquo; bundled with the most important piece of hardware of the decade.</p>
<p>They are celebrating their ascension to the throne. They do not realize they are reading their obituary.</p>
<p>By porting their fundamentally 8-bit application to IBM&rsquo;s new 16-bit architecture without significantly rewriting it to take advantage of the expanded memory and speed, VisiCalc left the door wide open. Just over a year later, a former VisiCorp product manager named <a href="/mitch-kapor/">Mitch Kapor</a> would release Lotus 1-2-3. Written directly in x86 assembly to ruthlessly exploit the IBM PC&rsquo;s hardware, Lotus would make VisiCalc look like a sluggish, archaic toy. VisiCalc&rsquo;s sales would flatline almost overnight.</p>
<p>But wait a second: did I not just publish <a href="/behold-the-app-killers/">an article</a> in this very edition that literally enumerates rewriting as one of the &ldquo;App Killer&rdquo; factors? Well, yes, but in some cases app rewritings were required; if not in version 1.0, in version 1.1, particularly when you have such technological transitions as the one witnessed in August 1981. Of course, it is easy to pass judgment in hindsight… 45 years after the facts. Anyway, I digress, as usual. Who knows what history would have been like if VisiCalc had made it to the 1990s? Would our accountants be calculating our taxes with &ldquo;VisiCalc for Windows 2026&rdquo; today?</p>
<p>Back to Software Arts. As the meeting unfolds, Bricklin reads off the software lineup for the new machine: a <a href="/programming-the-liberal-arts/">BASIC</a> interpreter from Microsoft, a word-processing app called <a href="https://en.wikipedia.org/wiki/EasyWriter">EasyWriter</a>, and an accounting package from Peachtree. Such was the primordial soup of a new computer back in the day. Neither Doom nor <a href="/lazarus-come-forth/">Pascal</a> nor <a href="/where-are-the-killer-apps/">Facebook</a> nor ChatGPT were &ldquo;Killing Apps&rdquo; yet in the collective psyche.</p>
<p>The deepest irony arrives precisely at <a href="https://youtu.be/uDsU9wyQ5Ks?t=426">minute 7:06</a>, when Bricklin highlights IBM&rsquo;s &ldquo;groundbreaking decision&rdquo; to open a software publishing department to consider user-generated programs and third-party software. He reads this as an exciting curiosity. In reality, it was the death knell of the closed-silo computing appliance. IBM was building an open platform, and an open platform has no loyalty to its launch titles. The very ecosystem that Software Arts was helping to legitimize was the exact mechanism that would allow their competitors to bypass them entirely.</p>
<p>Pause at <a href="https://youtu.be/uDsU9wyQ5Ks?t=628">minute 10:28</a> and pay attention to the marketing materials they pass around, featuring a bizarre stock photo of a wife adoringly holding onto her husband as a child plays on the PC, accompanied by pictures of cows meant to represent VisiCalc. They laugh at the marketing department&rsquo;s clumsy attempts to visualize software. They are dissecting the marketing of a product that they believe guarantees their future, entirely blind to the fact that the IBM PC was merely a vessel for their impending obsolescence.</p>
<p>We often look back at the history of startup culture through the lens of polished retrospectives and survivorship bias. We read about the early days of computing and imagine a clean, inevitable trajectory where the pioneers always reap the rewards of their labor. This video shatters that illusion. It is a beautiful, unvarnished, and quietly tragic look at the exact moment a company reached its absolute zenith. Look at them: they are sitting in a sweltering room in 1981, laughing, smiling, and holding the future in their hands, blissfully unaware of the plans the future was already making to leave them behind.</p>
<p>VisiCalc, their own quintessential &ldquo;Killer App,&rdquo; the one that quite rightfully defined a whole generation of computers, was about to be murdered and rendered obsolete in that savage, never-ending ritual of the software industry. I just read again this last phrase, and I cannot believe how corny it sounds, but so be it. I like corny.</p>
<p>Cover snapshot chosen by the author.</p>
]]></content:encoded></item><item><title>Chris Zamara &amp; Nick Sullivan</title><link>https://deprogrammaticaipsum.com/chris-zamara-nick-sullivan/</link><pubDate>Mon, 06 Jul 2026 05:00:02 +0200</pubDate><guid>https://deprogrammaticaipsum.com/chris-zamara-nick-sullivan/</guid><description><![CDATA[ <p>The mid-1980s was the era when the personal computing vendors ended their war on themselves. In the belligerent phase, every time a vendor released a new computer, it was incompatible with everything that came before it. In <a href="/where-are-the-killer-apps/">&ldquo;Where Are The Killer Apps?&rdquo;</a>, I showed that Commodore VIC-20 software does not run on the Commodore 64, or any other computer made by the same company or another company. The same was true for Apple: try running Apple 1 software on an Apple ][, Apple ///, Lisa, or Macintosh (or these days, try to run Macintosh software from a decade ago on a Macintosh); of Sinclair: you cannot run ZX80 software on a ZX81, Spectrum, or QL; and Tandy/Radio Shack: you cannot run TRS-80 Model I software on a TRS-80 Model II, on a TRS-80 Color Computer, or a Model 100.</p>]]></description><content:encoded><![CDATA[ <p>The mid-1980s was the era when the personal computing vendors ended their war on themselves. In the belligerent phase, every time a vendor released a new computer, it was incompatible with everything that came before it. In <a href="/where-are-the-killer-apps/">&ldquo;Where Are The Killer Apps?&rdquo;</a>, I showed that Commodore VIC-20 software does not run on the Commodore 64, or any other computer made by the same company or another company. The same was true for Apple: try running Apple 1 software on an Apple ][, Apple ///, Lisa, or Macintosh (or these days, try to run Macintosh software from a decade ago on a Macintosh); of Sinclair: you cannot run ZX80 software on a ZX81, Spectrum, or QL; and Tandy/Radio Shack: you cannot run TRS-80 Model I software on a TRS-80 Model II, on a TRS-80 Color Computer, or a Model 100.</p>
<p>For individual customers, this meant a huge upheaval whenever they bought a new computer (which was only once every decade or so at the time), as all of their programs, and all of their data, and most of their peripherals, and half of the BASIC keywords they had learned and all the memory locations to <code>PEEK</code> and <code>POKE</code>, all stopped working with the new system. It also meant huge questions for potential new customers: will software houses still support this computer six months from now? How about peripheral makers? Will my investment pay off?</p>
<p>So then came the era when the vendors made peace with themselves, and they started making compatible model families, which could all (more-or-less) run the same software, and use the same peripherals. They finally learned the lesson of IBM&rsquo;s System/360, and of course the runaway example of the compatible model family is the IBM PC and its legion of clones. Alongside that, TRS-80 Model III and IV both run TRS-80 Model I software; The ZX Spectrum 128k, +2, and +3 all run ZX Spectrum software; the Macintosh remained compatible with its original model&rsquo;s software up until Mac OS X 10.5; and all versions of the Amiga could more-or-less run anything designed for the original Amiga 1000.</p>
<p>Now it was safer for customers to buy into a platform, because it looked more likely that they would still be able to get applications (OK, let us be honest, games) and peripherals for the computer a few years out, and that the next time they bought a computer, they might be able to get one that can still use all those games and peripherals. But what would make any one platform more compelling than the others; what gets a customer to hitch their cart to Apple&rsquo;s horses instead of Commodore&rsquo;s? By the mid-1990s, all of the platforms that were still on the market had roughly compatible capabilities, with sound being the weird outlier: Apple Computer had settled the suit with Apple Corps and were allowed to play sounds on their computers; PCs were starting to transition from either beeps-only or CD-quality Sound Blasters to CD-quality integrated sound chips; Atari had integrated MIDI capabilities into the ST line all along; Amiga was the laggard, with its 1985 standard-setting Paula chip still the only option in the final CD32 model.</p>
<p>The vendors needed killer apps, but they needed a particular, very constrained, kind of killer app. Something that made their platform more compelling, but that did not crowd out independent software vendors. Something that made everybody else&rsquo;s software better on their computers, and also made their own software better on their computers.</p>
<p>For a brief period, it looked like this killer app was going to be interoperability, and empowerment. Each platform supplied its own, unique way to interconnect software into a platform-wide automation capability that let the vendor&rsquo;s customers write scripts, or record macros, that used first-party and third-party software in concert to perform complicated tasks. It was a beautiful time; perhaps the last time that the computer vendors trusted us to know what we wanted and enabled us to go the last mile ourselves.</p>
<p>Windows 95 supplied <a href="https://en.wikipedia.org/wiki/Windows_Script_Host">Windows Script Host</a>, which could communicate with any app on the platform using <a href="https://en.wikipedia.org/wiki/Component_Object_Model">COM</a>. Apple provided <a href="https://developer.apple.com/library/archive/documentation/LanguagesUtilities/Conceptual/MacAutomationScriptingGuide/HowMacScriptingWorks.html">Open Scripting Architecture</a>, which apps could integrate with to make their capabilities available to people who wrote AppleScript. Two other platforms—IBM and Microsoft&rsquo;s ill-fated OS/2, and Commodore&rsquo;s ill-fated Amiga—adopted an interpreted language from IBM as the interface to their interoperability features: <a href="https://en.wikipedia.org/wiki/Rexx">Rexx</a>.</p>
<p>Amiga Rexx (ARexx) was not actually Commodore&rsquo;s idea, it was created by William S. Hawes as a third-party product, but Commodore saw the value and incorporated it into AmigaOS 2.0 and every subsequent release, from 1990. Rexx itself is a nice, PL/1-like language with some interesting features: it does not have arrays or dictionaries, but it does have &ldquo;stem variables&rdquo;, so the variables named <code>a.1</code> and <code>a.2</code> are associated through the stem <code>a</code>, and if another variable <code>i</code> has the value <code>2</code>, then the value of <code>a.i</code> is whatever you assigned to <code>a.2</code>.</p>
<p>What sets ARexx apart and makes it a candidate for empowerment feature of the (last) century is the idea of the command host. Just like AppleScript&rsquo;s <code>tell application &quot;Finder&quot;</code> instructs the script interpreter to send a message over to the Finder app, ARexx&rsquo;s <code>address 'DPaint'</code> tells the interpreter to connect to the port for the DPaint app.  The app does whatever the Rexx script requests, and then replies to the message.</p>
<p>What the application receives is a message containing the string was addressed to it, which it can parse using the same format specifiers that CLI tools use in the AmigaDOS shell: the first word is the command name (i.e. the verb) and everything else is a modifier, or parameter. In this way, the syntax is relatively free, but still relatively programming-like, avoiding the trap of feeling like natural language but interpreting input in surprising ways. This problem befell AppleScript, where author Matt Neuberg described it as the &ldquo;English-likeness&rdquo; monster.</p>
<p>In this way, ARexx acts as the universal glue that makes Amiga applications part of a powerful suite of interconnected tools, <em>designed, assembled, and controlled</em> by the person using the computer. During this period where a platform vendor&rsquo;s agent has more access to the apps and content on a computer than its customers do, the suppliers would be well served by remembering a time when they tried to empower their customers, and make sure that the world of computing did not turn out like <em>Nineteen Eighty-Four</em>.</p>
<p>Cover photo by the author.</p>
]]></content:encoded></item><item><title>Issue 093: Functional Programming</title><link>https://deprogrammaticaipsum.com/issue-093-functional-programming/</link><pubDate>Mon, 01 Jun 2026 05:03:00 +0200</pubDate><guid>https://deprogrammaticaipsum.com/issue-093-functional-programming/</guid><description><![CDATA[ <p>Welcome to the 93rd issue of <em>De Programmatica Ipsum</em>, about <em>Functional Programming</em>.</p>
<p>In this edition:</p>
<ul>
<li>Graham <a href="/evading-von-neumann/">explains the benefits</a> of solving problems with a functional mindset.</li>
<li>Adrian explores <a href="/functional-programming-the-good-parts/">why functional programming was shunned</a> until it was not.</li>
<li>In our <a href="/category/videotheque/">Vidéothèque section</a>, we watch <a href="/joe-armstrong/">Joe Armstrong</a> explain how functional programming made Erlang a reality.</li>
<li>In the <a href="/category/library/">Library section</a>, we review the most important papers by <a href="/philip-wadler/">Philip Wadler</a>, <a href="/guy-steele-gerry-sussman/">Guy Steele, and Gerry Sussman</a>.</li>
</ul>
<p>Download this issue in DRM-free <a href="/pdf/issue-093-functional-programming.pdf">PDF</a> or <a href="/epub/issue-093-functional-programming.epub">EPUB</a> format, and read it on your preferred device. You can also subscribe to <a href="/index.xml">our RSS feed</a>, featuring the full content of our articles.</p>]]></description><content:encoded><![CDATA[ <p>Welcome to the 93rd issue of <em>De Programmatica Ipsum</em>, about <em>Functional Programming</em>.</p>
<p>In this edition:</p>
<ul>
<li>Graham <a href="/evading-von-neumann/">explains the benefits</a> of solving problems with a functional mindset.</li>
<li>Adrian explores <a href="/functional-programming-the-good-parts/">why functional programming was shunned</a> until it was not.</li>
<li>In our <a href="/category/videotheque/">Vidéothèque section</a>, we watch <a href="/joe-armstrong/">Joe Armstrong</a> explain how functional programming made Erlang a reality.</li>
<li>In the <a href="/category/library/">Library section</a>, we review the most important papers by <a href="/philip-wadler/">Philip Wadler</a>, <a href="/guy-steele-gerry-sussman/">Guy Steele, and Gerry Sussman</a>.</li>
</ul>
<p>Download this issue in DRM-free <a href="/pdf/issue-093-functional-programming.pdf">PDF</a> or <a href="/epub/issue-093-functional-programming.epub">EPUB</a> format, and read it on your preferred device. You can also subscribe to <a href="/index.xml">our RSS feed</a>, featuring the full content of our articles.</p>
<p>We would like to thank our patrons who generously contribute every month (or have contributed in the past) to our work and help us run this magazine. Thank you so much! In alphabetical order: Adam Guest, Adrian Tineo Cabello, Benjamin Sheldon, Christopher Nascone, Colin Powell, Franz Lucien Moersdorf, Guillermo Ramos Álvarez, Jean-Paul de Vooght, Dr. Juande Santander-Vela, Patryk Matuszewski, Paul Hudson, Quico Moya, Roger Turner, Szymon Licau, and countless more leaving anonymous tips every month.</p>
<p>Enjoy this issue! Please share our articles on social media, or <a href="/contribute/">contribute</a> if you would like to support our work with a donation via <a href="https://liberapay.com/akosma/donate">Liberapay</a>.</p>
<p>Cover photo by <a href="https://unsplash.com/@fakurian?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Milad Fakurian</a> on <a href="https://unsplash.com/photos/a-purple-object-with-a-shadow-on-the-ground-Em8glt2OLt0?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a>.</p>
]]></content:encoded></item><item><title>Evading Von Neumann</title><link>https://deprogrammaticaipsum.com/evading-von-neumann/</link><pubDate>Mon, 01 Jun 2026 05:02:02 +0200</pubDate><guid>https://deprogrammaticaipsum.com/evading-von-neumann/</guid><description> &lt;p>Programming styles are supposed to be &lt;em>paradigmatic&lt;/em>, in that they structure your thinking about creating software by providing unifying theories and methods that you use to plan, design, construct, and operate your software. In that sense, the way that you think about the software is everything, and the tools that you use are nothing.&lt;/p></description><content:encoded><![CDATA[ <p>Programming styles are supposed to be <em>paradigmatic</em>, in that they structure your thinking about creating software by providing unifying theories and methods that you use to plan, design, construct, and operate your software. In that sense, the way that you think about the software is everything, and the tools that you use are nothing.</p>
<p>Take <a href="/issue/issue-049-object-oriented-programming/">object-oriented programming</a>, for example. Selecting Java as an implementation language does not immediately mean that your solution is object-oriented (though it may have been sufficient to get you some OOP-linked venture capital at the <a href="/the-hype-cycle-of-oop/">peak of the hype cycle</a>). Similarly, when you see an implementation language that does not have object features, FORTRAN-77 for example, that does not mean that you are not looking at the source code of software built using the object-oriented paradigm.</p>
<p>But this is the issue on functional programming, not OOP. The paradigmatic basis of functional programming is that you design your program as algebraic transformations of structured data types. This affects how you discuss your program with stakeholders, how you model requirements, how you architect solutions and deployment…it is not just a matter of reaching for Haskell (indeed using the <code>do</code> form it is very easy to write procedural software in Haskell anyway).</p>
<p>You compose large programs by combining algebraic transformations into more complex operations. As such, you define transformations that are composable. This composability comes from designing transformations with clear contracts and interfaces, so that the result of applying the transformation is evident and safe in the context of the composition. For example, imagine that you have a need to double every element in a list of numbers. It is easy in many imperative languages to write a loop that iterates over the list and multiplies each number by 2. But thinking about this &ldquo;problem&rdquo; using the paradigm of composing algebraic transformations, you can build the solution from two components:</p>
<ol>
<li>Apply an operation to every element of a list.</li>
<li>Multiply a number by 2.</li>
</ol>
<p>So now you can build two functions, which are demonstrated as procedures written in <a href="/issue/issue-065-pascal/">Pascal</a> here because, as I said, tool use is not paradigmatic; and besides, Pascal and Haskell nearly rhyme and both languages are named after mathematicians, so they are almost the same thing. The first function to create is the <code>Map</code> function, which applies a function to every element in a collection and returns a collection of the results:</p>
<div class="highlight"><pre tabindex="0" style="background-color:#eed;-moz-tab-size:2;-o-tab-size:2;tab-size:2;-webkit-text-size-adjust:none;"><code class="language-objectpascal" data-lang="objectpascal"><span style="display:flex;"><span><span style="color:#8b008b;font-weight:bold">unit</span><span style="color:#bbb"> </span>Functional;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#8b008b;font-weight:bold">interface</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#8b008b;font-weight:bold">type</span>
</span></span><span style="display:flex;"><span><span style="color:#bbb">  </span>generic<span style="color:#bbb"> </span>TArrayU&lt;U&gt;<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#8b008b;font-weight:bold">array</span><span style="color:#bbb"> </span><span style="color:#8b008b;font-weight:bold">of</span><span style="color:#bbb"> </span>U;
</span></span><span style="display:flex;"><span><span style="color:#bbb">  </span>generic<span style="color:#bbb"> </span>TMapFunc&lt;T,<span style="color:#bbb"> </span>U&gt;<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>function(<span style="color:#8b008b;font-weight:bold">const</span><span style="color:#bbb"> </span>Item:<span style="color:#bbb"> </span>T):<span style="color:#bbb"> </span>U;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>generic<span style="color:#bbb"> </span><span style="color:#8b008b;font-weight:bold">function</span><span style="color:#bbb"> </span>Map&lt;T,<span style="color:#bbb"> </span>U&gt;(<span style="color:#8b008b;font-weight:bold">const</span><span style="color:#bbb"> </span>Arr:<span style="color:#bbb"> </span><span style="color:#8b008b;font-weight:bold">array</span><span style="color:#bbb"> </span><span style="color:#8b008b;font-weight:bold">of</span><span style="color:#bbb"> </span>T;<span style="color:#bbb"> </span>Func:
</span></span><span style="display:flex;"><span><span style="color:#bbb">    </span>specialize<span style="color:#bbb"> </span>TMapFunc&lt;T,<span style="color:#bbb"> </span>U&gt;):
</span></span><span style="display:flex;"><span><span style="color:#bbb">    </span>specialize<span style="color:#bbb"> </span>TArrayU&lt;U&gt;;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#8b008b;font-weight:bold">implementation</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>generic<span style="color:#bbb"> </span><span style="color:#8b008b;font-weight:bold">function</span><span style="color:#bbb"> </span>Map&lt;T,<span style="color:#bbb"> </span>U&gt;(<span style="color:#8b008b;font-weight:bold">const</span><span style="color:#bbb"> </span>Arr:<span style="color:#bbb"> </span><span style="color:#8b008b;font-weight:bold">array</span><span style="color:#bbb"> </span><span style="color:#8b008b;font-weight:bold">of</span><span style="color:#bbb"> </span>T;<span style="color:#bbb"> </span>Func:
</span></span><span style="display:flex;"><span><span style="color:#bbb">    </span>specialize<span style="color:#bbb"> </span>TMapFunc&lt;T,<span style="color:#bbb"> </span>U&gt;):
</span></span><span style="display:flex;"><span><span style="color:#bbb">    </span>specialize<span style="color:#bbb"> </span>TArrayU&lt;U&gt;;
</span></span><span style="display:flex;"><span><span style="color:#8b008b;font-weight:bold">var</span>
</span></span><span style="display:flex;"><span><span style="color:#bbb">  </span>i:<span style="color:#bbb"> </span><span style="color:#00688b;font-weight:bold">Integer</span>;
</span></span><span style="display:flex;"><span><span style="color:#8b008b;font-weight:bold">begin</span>
</span></span><span style="display:flex;"><span><span style="color:#bbb">  </span><span style="font-style:italic">Result</span><span style="color:#bbb"> </span>:=<span style="color:#bbb"> </span><span style="color:#8b008b;font-weight:bold">nil</span>;
</span></span><span style="display:flex;"><span><span style="color:#bbb">  </span>SetLength(<span style="font-style:italic">Result</span>,<span style="color:#bbb"> </span>Length(Arr));
</span></span><span style="display:flex;"><span><span style="color:#bbb">  </span><span style="color:#8b008b;font-weight:bold">for</span><span style="color:#bbb"> </span>i<span style="color:#bbb"> </span>:=<span style="color:#bbb"> </span><span style="color:#b452cd">0</span><span style="color:#bbb"> </span><span style="color:#8b008b;font-weight:bold">to</span><span style="color:#bbb"> </span>High(Arr)<span style="color:#bbb"> </span><span style="color:#8b008b;font-weight:bold">do</span>
</span></span><span style="display:flex;"><span><span style="color:#bbb">    </span><span style="font-style:italic">Result</span>[i]<span style="color:#bbb"> </span>:=<span style="color:#bbb"> </span>Func(Arr[i]);
</span></span><span style="display:flex;"><span><span style="color:#8b008b;font-weight:bold">end</span>;
</span></span><span style="display:flex;"><span><span style="color:#8b008b;font-weight:bold">end</span>.
</span></span></code></pre></div><p>The generic interface for the <code>Map</code> function means that even if you did not look at the implementation, you would know something about how it works. Its inputs are an array of <code>T</code>, and a function that turns <code>T</code> into <code>U</code>, and its output is an array of <code>U</code>. Nowhere is anything specified about <code>T</code> or <code>U</code>. That means that the function cannot use any of the operations available on either <code>T</code> or <code>U</code>, so if there is a <code>U</code> in the output the <em>only</em> way that <code>Map</code> created it was by applying the function to one of the <code>T</code>s in its input.</p>
<p>Unfortunately Pascal arrays have a rich interface so it is impossible to say anything about <em>which</em> <code>T</code>s get turned into <code>U</code>s; the function might always return <code>nil</code>, for example. The implementation shows that this Pascal <code>Map</code> works as you might expect a <code>map</code> function; it applies the <code>Func</code> parameter to each <code>T</code> in the input array, and returns an array where the corresponding <code>U</code> is at the same index as the given <code>T</code>.</p>
<p>The second function you create is the <code>DoubleInt</code> function that multiples a number by 2 and returns the result:</p>
<div class="highlight"><pre tabindex="0" style="background-color:#eed;-moz-tab-size:2;-o-tab-size:2;tab-size:2;-webkit-text-size-adjust:none;"><code class="language-objectpascal" data-lang="objectpascal"><span style="display:flex;"><span><span style="color:#8b008b;font-weight:bold">function</span><span style="color:#bbb"> </span>DoubleInt(<span style="color:#8b008b;font-weight:bold">const</span><span style="color:#bbb"> </span>i:<span style="color:#bbb"> </span><span style="color:#00688b;font-weight:bold">Integer</span>):<span style="color:#bbb"> </span><span style="color:#00688b;font-weight:bold">Integer</span>;
</span></span><span style="display:flex;"><span><span style="color:#8b008b;font-weight:bold">begin</span>
</span></span><span style="display:flex;"><span><span style="color:#bbb">  </span><span style="font-style:italic">Result</span><span style="color:#bbb"> </span>:=<span style="color:#bbb"> </span>i<span style="color:#bbb"> </span>*<span style="color:#bbb"> </span><span style="color:#b452cd">2</span>;
</span></span><span style="display:flex;"><span><span style="color:#8b008b;font-weight:bold">end</span>;
</span></span></code></pre></div><p>Here the interface does not help much at all: the input is an <code>Integer</code>, and the result is an <code>Integer</code>. The function might always return a constant, or square the input, or add it to a constant, or convert it into a <code>String</code>, reverse the characters, and convert that back into an <code>Integer</code> to return. This demonstrates the power of generic component design: the less information available about the types used in a function, the more constraints on the behavior of that function, so the easier that function is to understand.</p>
<p>Now you solve the problem by composing <code>DoubleInt</code> and <code>Map</code>:</p>
<div class="highlight"><pre tabindex="0" style="background-color:#eed;-moz-tab-size:2;-o-tab-size:2;tab-size:2;-webkit-text-size-adjust:none;"><code class="language-objectpascal" data-lang="objectpascal"><span style="display:flex;"><span><span style="color:#8b008b;font-weight:bold">program</span><span style="color:#bbb"> </span>Main;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#8b008b;font-weight:bold">uses</span>
</span></span><span style="display:flex;"><span><span style="color:#bbb">  </span>Functional,<span style="color:#bbb"> </span>SysUtils;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#8b008b;font-weight:bold">type</span>
</span></span><span style="display:flex;"><span><span style="color:#bbb">  </span>TIntArray<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#8b008b;font-weight:bold">array</span><span style="color:#bbb"> </span><span style="color:#8b008b;font-weight:bold">of</span><span style="color:#bbb"> </span><span style="color:#00688b;font-weight:bold">Integer</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#8b008b;font-weight:bold">var</span>
</span></span><span style="display:flex;"><span><span style="color:#bbb">  </span>Ints,<span style="color:#bbb"> </span>Doubled:<span style="color:#bbb"> </span>TIntArray;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#8b008b;font-weight:bold">begin</span>
</span></span><span style="display:flex;"><span><span style="color:#bbb">  </span>Ints<span style="color:#bbb"> </span>:=<span style="color:#bbb"> </span>TIntArray.Create(<span style="color:#b452cd">1</span>,<span style="color:#bbb"> </span><span style="color:#b452cd">2</span>,<span style="color:#bbb"> </span><span style="color:#b452cd">3</span>,<span style="color:#bbb"> </span><span style="color:#b452cd">4</span>,<span style="color:#bbb"> </span><span style="color:#b452cd">5</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#bbb">  </span>Write(<span style="color:#cd5555">&#39;Original: &#39;</span>);
</span></span><span style="display:flex;"><span><span style="color:#bbb">  </span><span style="color:#8b008b;font-weight:bold">for</span><span style="color:#bbb"> </span>i<span style="color:#bbb"> </span><span style="color:#8b008b;font-weight:bold">in</span><span style="color:#bbb"> </span>Ints<span style="color:#bbb"> </span><span style="color:#8b008b;font-weight:bold">do</span><span style="color:#bbb"> </span>Write(i,<span style="color:#bbb"> </span><span style="color:#cd5555">&#39; &#39;</span>);
</span></span><span style="display:flex;"><span><span style="color:#bbb">  </span>WriteLn;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#bbb">  </span>Doubled<span style="color:#bbb"> </span>:=<span style="color:#bbb"> </span>specialize<span style="color:#bbb"> </span>Map&lt;<span style="color:#00688b;font-weight:bold">Integer</span>,<span style="color:#bbb"> </span><span style="color:#00688b;font-weight:bold">Integer</span>&gt;(Ints,<span style="color:#bbb"> </span>@DoubleInt);
</span></span><span style="display:flex;"><span><span style="color:#bbb">  </span>Write(<span style="color:#cd5555">&#39;Mapped (Double): &#39;</span>);
</span></span><span style="display:flex;"><span><span style="color:#bbb">  </span><span style="color:#8b008b;font-weight:bold">for</span><span style="color:#bbb"> </span>i<span style="color:#bbb"> </span><span style="color:#8b008b;font-weight:bold">in</span><span style="color:#bbb"> </span>Doubled<span style="color:#bbb"> </span><span style="color:#8b008b;font-weight:bold">do</span><span style="color:#bbb"> </span>Write(i,<span style="color:#bbb"> </span><span style="color:#cd5555">&#39; &#39;</span>);
</span></span><span style="display:flex;"><span><span style="color:#bbb">  </span>WriteLn;
</span></span><span style="display:flex;"><span><span style="color:#8b008b;font-weight:bold">end</span>.
</span></span></code></pre></div><p>These two functions are very simple mappings of their input to their output. You could imagine implementing <code>DoubleInt</code> as a lookup table, where the value at index <code>0</code> is <code>0</code>, the value at index <code>1</code> is <code>2</code>, and so on. In principle you could do the same for <code>Map</code> but it would be a very tedious table to write, and it would lose the simplicity of using the <code>Func</code> parameter to achieve the transformation.</p>
<p>A problem for composability arises when you want to use a program to <em>do</em> something; to store or retrieve a result, or to interact with its environment. These kinds of computations do not show up in the function signature, so you cannot tell the difference between &ldquo;function that accepts a list of <code>T</code> and returns a <code>Boolean</code>&rdquo; and &ldquo;function that accepts a list of <code>T</code>, drops all tables in the database, and returns a <code>Boolean</code>&rdquo;. It is harder to build functions into reusable workflows when they might have side effects like that.</p>
<p>A solution used by people who think in the functional way is <a href="https://learnyouahaskell.github.io/a-fistful-of-monads.html">monads</a>, a class of types that associate values with context and enables computations on the values while maintaining the association with the context. Again, because there is nothing special about programming language choice, you can build that in Pascal:</p>
<div class="highlight"><pre tabindex="0" style="background-color:#eed;-moz-tab-size:2;-o-tab-size:2;tab-size:2;-webkit-text-size-adjust:none;"><code class="language-objectpascal" data-lang="objectpascal"><span style="display:flex;"><span><span style="color:#8b008b;font-weight:bold">unit</span><span style="color:#bbb"> </span>Monads;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#8b008b;font-weight:bold">interface</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#8b008b;font-weight:bold">type</span>
</span></span><span style="display:flex;"><span><span style="color:#bbb">  </span>generic<span style="color:#bbb"> </span>IMonad&lt;T&gt;<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#8b008b;font-weight:bold">interface</span>
</span></span><span style="display:flex;"><span><span style="color:#bbb">    </span>[<span style="color:#cd5555">&#39;{7A8D8C30-5A2C-4B9F-8F8D-9E9C9B9A9D9E}&#39;</span>]
</span></span><span style="display:flex;"><span><span style="color:#bbb">    </span><span style="color:#8b008b;font-weight:bold">function</span><span style="color:#bbb"> </span>Execute:<span style="color:#bbb"> </span>T;
</span></span><span style="display:flex;"><span><span style="color:#bbb">  </span><span style="color:#8b008b;font-weight:bold">end</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#bbb">  </span>generic<span style="color:#bbb"> </span>TIOReturn&lt;T&gt;<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>class(TInterfacedObject,<span style="color:#bbb"> </span>specialize<span style="color:#bbb"> </span>IMonad&lt;T&gt;)
</span></span><span style="display:flex;"><span><span style="color:#bbb">  </span><span style="color:#8b008b;font-weight:bold">private</span>
</span></span><span style="display:flex;"><span><span style="color:#bbb">    </span>FVal:<span style="color:#bbb"> </span>T;
</span></span><span style="display:flex;"><span><span style="color:#bbb">  </span><span style="color:#8b008b;font-weight:bold">public</span>
</span></span><span style="display:flex;"><span><span style="color:#bbb">    </span><span style="color:#8b008b;font-weight:bold">constructor</span><span style="color:#bbb"> </span>Create(<span style="color:#8b008b;font-weight:bold">const</span><span style="color:#bbb"> </span>V:<span style="color:#bbb"> </span>T);
</span></span><span style="display:flex;"><span><span style="color:#bbb">    </span><span style="color:#8b008b;font-weight:bold">function</span><span style="color:#bbb"> </span>Execute:<span style="color:#bbb"> </span>T;
</span></span><span style="display:flex;"><span><span style="color:#bbb">  </span><span style="color:#8b008b;font-weight:bold">end</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#bbb">  </span>generic<span style="color:#bbb"> </span>TIOBind&lt;A,<span style="color:#bbb"> </span>B&gt;<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>class(TInterfacedObject,<span style="color:#bbb"> </span>specialize<span style="color:#bbb"> </span>IMonad&lt;B&gt;)
</span></span><span style="display:flex;"><span><span style="color:#bbb">  </span><span style="color:#8b008b;font-weight:bold">public</span>
</span></span><span style="display:flex;"><span><span style="color:#bbb">    </span><span style="color:#8b008b;font-weight:bold">type</span>
</span></span><span style="display:flex;"><span><span style="color:#bbb">      </span>TBF<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>function(<span style="color:#8b008b;font-weight:bold">const</span><span style="color:#bbb"> </span>V:<span style="color:#bbb"> </span>A):<span style="color:#bbb"> </span>specialize<span style="color:#bbb"> </span>IMonad&lt;B&gt;;
</span></span><span style="display:flex;"><span><span style="color:#bbb">  </span><span style="color:#8b008b;font-weight:bold">private</span>
</span></span><span style="display:flex;"><span><span style="color:#bbb">    </span>FPrev:<span style="color:#bbb"> </span>specialize<span style="color:#bbb"> </span>IMonad&lt;A&gt;;
</span></span><span style="display:flex;"><span><span style="color:#bbb">    </span>FFunc:<span style="color:#bbb"> </span>TBF;
</span></span><span style="display:flex;"><span><span style="color:#bbb">  </span><span style="color:#8b008b;font-weight:bold">public</span>
</span></span><span style="display:flex;"><span><span style="color:#bbb">    </span><span style="color:#8b008b;font-weight:bold">constructor</span><span style="color:#bbb"> </span>Create(<span style="color:#8b008b;font-weight:bold">const</span><span style="color:#bbb"> </span>P:<span style="color:#bbb"> </span>specialize<span style="color:#bbb"> </span>IMonad&lt;A&gt;;<span style="color:#bbb"> </span><span style="color:#8b008b;font-weight:bold">const</span><span style="color:#bbb"> </span>F:<span style="color:#bbb"> </span>TBF);
</span></span><span style="display:flex;"><span><span style="color:#bbb">    </span><span style="color:#8b008b;font-weight:bold">function</span><span style="color:#bbb"> </span>Execute:<span style="color:#bbb"> </span>B;
</span></span><span style="display:flex;"><span><span style="color:#bbb">  </span><span style="color:#8b008b;font-weight:bold">end</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#8b008b;font-weight:bold">implementation</span>
</span></span><span style="display:flex;"><span><span style="color:#228b22">{...}</span>
</span></span><span style="display:flex;"><span><span style="color:#8b008b;font-weight:bold">end</span>.
</span></span></code></pre></div><p>All this makes it look like there is nothing to a &ldquo;functional programming language&rdquo; other than the convenience of expressing paradigmatic functional thinking efficiently. For example, if you had access to a programming language that is like Pascal but also has partial application (function currying, to use Haskell Curry&rsquo;s family name) then you could create the <code>DoubleInt</code> function in the first example above by applying <code>2</code> to the <code>Multiply</code> function, and avoid needing to write a custom component for such a simple operation.</p>
<p>Using the idea that all <a href="https://en.wikipedia.org/wiki/Turing_completeness">computationally universal</a> models are equally powerful, you can do your functional thinking in your brain and then convert it into Haskell, Pascal, or even languages that do not rhyme and are not named after mathematicians. This statement, true as it goes, is not helpful. Functional programming as a style does benefit from specifically designed programming languages, that perform for software engineering what John Locke achieved for national goverment in the 17th Century: the separation of [Alonzo] Church and state.</p>
<p>The Pascal functions above might present interfaces that represent composable algebraic primitives, but under the hood their implementations are sequential applications of state transitions in a slightly abstracted version of the computer&rsquo;s memory. Pascal&rsquo;s model of computation might let it reorder some instructions a little, but fundamentally it, and similar languages like Algol, C, Rust, and Python, are there to make it easy for you to sequence changes to the computer&rsquo;s memory.</p>
<p>A goal of functional programming is to <a href="https://dl.acm.org/doi/10.1145/359576.359579">escape the von Neumann bottleneck</a>, describing programs in ways that are not limited by the sequencing of changes to memory states. Yes, that has to happen, but it does not have to be the programmer&rsquo;s responsibility. Instead, the programmer&rsquo;s task is to explain what the program should do, and the <em>computer&rsquo;s</em> task is to find an efficient way to do it. Tail-call recursion, lazy or applicative evaluation, memoization, parallelism—none of those are your problem.</p>
<p>The most widespread examples of programming tools that embody this notion of communicating intent, not computation, are query languages (and these days, coding AIs). You do not tell SQL, or LINQ, how to loop over the elements in a collection; you tell it which properties you want from what elements (for example, composing primitives expressed in the <a href="https://www.cbcb.umd.edu/confcour/Spring2014/CMSC424/Relational_algebra.pdf">Relational Algebra</a> like &ldquo;Select&rdquo; and &ldquo;Project&rdquo;), and <em>the computer</em> works out an efficient way to make that happen.</p>
<p>You can reap the benefits of functional thinking in whatever programming language you happen to use. To truly escape the clutches of von Neumann and take advantage of functional <em>computation</em>, you do in fact need to choose your tools wisely.</p>
<p>Horrific disestablishment pun by <a href="https://www.cs.ox.ac.uk/jeremy.gibbons/">Prof. Jeremy Gibbons</a>. Photo by <a href="https://unsplash.com/@sanketshah?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Sanket Shah</a> on <a href="https://unsplash.com/photos/cooked-food-in-black-cooking-pot-eEWlcfydzQ4?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a>.</p>
]]></content:encoded></item><item><title>Functional Programming: The Good Parts</title><link>https://deprogrammaticaipsum.com/functional-programming-the-good-parts/</link><pubDate>Mon, 01 Jun 2026 05:02:01 +0200</pubDate><guid>https://deprogrammaticaipsum.com/functional-programming-the-good-parts/</guid><description><![CDATA[ <p>In a <a href="https://dl.acm.org/doi/10.1145/286385.286387">famous paper</a> published in 1998, <a href="/philip-wadler/">Philip Wadler</a> complained that no one used functional programming languages. It is safe to say that in 2026 everybody is using some kind of functional programming language, albeit to a certain extent, but the underlying reason for this spread had more to do with fashion and hype rather than market economics or academic support.</p>]]></description><content:encoded><![CDATA[ <p>In a <a href="https://dl.acm.org/doi/10.1145/286385.286387">famous paper</a> published in 1998, <a href="/philip-wadler/">Philip Wadler</a> complained that no one used functional programming languages. It is safe to say that in 2026 everybody is using some kind of functional programming language, albeit to a certain extent, but the underlying reason for this spread had more to do with fashion and hype rather than market economics or academic support.</p>
<p>&ldquo;Modern&rdquo; programming languages include, almost without exception, features borrowed from the realm of functional programming languages. This can be briefly summarized as follows: &ldquo;lambdas&rdquo; or &ldquo;closures&rdquo; that can be passed around and called <em>a piacere</em>; a series of functions to manipulate arrays called <code>map()</code>, <code>filter()</code>, and <code>reduce()</code> (provided either as standalone functions or as methods of some <code>Array</code> class provided by the languages&rsquo; runtime libraries); immutable records or classes, guaranteed to be unchanged throughout the execution of the program; and sometimes even a &ldquo;pipe operator&rdquo; looking like this: <code>|&gt;</code>.</p>
<p>In the latter case, we can include the humble <a href="/the-toyota-corolla-of-programming/">PHP</a> programming language, which <a href="https://php.watch/versions/8.5/pipe-operator">features</a> such a contraption since version 8.5, released last November at the time of this writing. Which means that the two statements below produce similar results:</p>
<div class="highlight"><pre tabindex="0" style="background-color:#eed;-moz-tab-size:2;-o-tab-size:2;tab-size:2;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#00688b">$result1</span> = trim(str_shuffle(strtoupper(<span style="color:#cd5555">&#34;hello&#34;</span>)));
</span></span><span style="display:flex;"><span><span style="color:#00688b">$result2</span> = strtoupper(<span style="color:#cd5555">&#34;hello&#34;</span>) |&gt; <span style="color:#cd5555">&#39;str_shuffle&#39;</span> |&gt; trim(...);
</span></span></code></pre></div><p>Spoiler alert: the ellipsis (since PHP 8.1) makes a closure out of a pre-existing function, but as shown above, you can just use a string with the name of the function you would like to &ldquo;pipe&rdquo; your output into. Oh, and beware of the fact that <code>array_map()</code> takes the callback function as the <em>first</em> argument rather than the second, which means that… you need a wrapper to invert the arguments. Yeah, as one author <a href="https://dev.to/delacry/php-85s-pipe-operator-hits-a-wall-on-array-code-5c7e">describes</a> the current situation in PHP,</p>
<blockquote>
<p>The deeper issue is the stdlib itself. PHP&rsquo;s stdlib was never shaped for chaining. array_map and array_filter taking arguments in different orders is a 1995 design that calcified before anyone thought about composition. The pipe operator works around the symptom. Native methods on arrays and strings would fix the cause.</p>
</blockquote>
<p>(Takes a deep breath.)</p>
<p>Other than such small shenanigans, and thanks to the introduction of the pipe operator, recently laid-off developers coming from the F#, Elixir, OCaml, Elm, or Julia galaxies should now feel at home with PHP (well, almost). Note to Haskell developers struggling to pay rent and willing to jump on the very lucrative market of PHP: in your case the pipe operator looks like an <code>&amp;</code>. You have been warned. Oh, and JavaScript developers will have to wait for their own pipe operator, but <a href="https://github.com/tc39/proposal-pipeline-operator">it might happen</a> sooner than expected.</p>
<p>Let us be even more radical: <a href="https://www.youtube.com/shorts/YPSGL2MsES4">according to Kevlin Henney</a>, Excel is the world&rsquo;s most popular functional programming language, and even better, it now comes <a href="https://www.youtube.com/watch?v=Rm4y5UqauRw">bundled</a> with a <code>LAMBDA()</code> function. How about that?</p>
<p>Are these features enough to make PHP (or Excel) a <em>real</em> functional programming language? Let us recap. Closures? <a href="https://www.php.net/manual/en/class.closure.php">Check</a>. Map, filter, and reduce functions? Check. Readonly classes? <a href="https://wiki.php.net/rfc/readonly_classes">Check</a>. Pipe operator? As we have seen above, check.</p>
<p>But of course, no, PHP is not really a <em>pure</em> functional programming language. It still allows for side effects, and that is a big no-no-no in that world. Even worse, it is quite obviously a procedural language, not really a declarative one. But with a little bit of attention, and maybe with the help of your preferred LLM-powered IDE and some unit tests, your PHP code can reach levels of &ldquo;functional compliance&rdquo; Rasmus Lerdorf could only dream of (well, perhaps he never dreamt of such a thing; I give you that).</p>
<p>The real question is the following: why does a parochial programming language such as PHP now include these features? The reasons behind the choice to add them as part of the specification have a strong element of hype.</p>
<p>The jump to <a href="/the-age-of-concurrency/">concurrency</a> and the economics of <a href="/somebody-elses-computer-as-a-service/">cloud computing</a> have given functional programming constructs a boost that neither desktop nor mainframe applications ever could. Let us be honest here: in the world of concurrency, multicore CPUs, at the end of the &ldquo;free lunch&rdquo; world, functional languages shine.</p>
<p>The trend was apparent at the beginning of the 2000s, and it simply exploded during the 2010s. Scala was released in 2004, becoming the first functional programming language built on top of the JVM; standard Java developers would have to wait until Java 8 (released in 2014) to be able to write code including lambda expressions and its associated <code>map</code>, <code>filter</code>, and <code>reduce</code> functions. On the other side, the C# community discovered <a href="https://learn.microsoft.com/en-us/dotnet/csharp/linq/">LINQ</a> in 2005 already, effectively transforming array manipulation into a SQL-like contraption. In the galaxy of Apple, Objective-C blocks and their associated <a href="https://fuckingblocksyntax.com/">arcane syntax</a> appeared together with <a href="https://en.wikipedia.org/wiki/Grand_Central_Dispatch">Grand Central Dispatch</a> around 2009. C++ debuted lambda expressions in its <a href="https://en.cppreference.com/cpp/language/lambda">specification</a> in 2011.</p>
<p>Languages created in the past 20 years almost inevitably include one or another of the functional programming features enumerated above: Go functions are first-class objects. TypeScript builds on top of the already existing JavaScript language. Rust closures come in various &ldquo;traits&rdquo; depending on how they capture their surrounding environment. Elixir brought closures on top of the Erlang BEAM. Dart has supported closures since its first version. F# brought rather pure functional programming features to the .NET runtime. Swift had first-class functions from day one, and for a while, even object-oriented methods were implemented as closures. Finally, Kotlin brought a shorter, simpler syntax for closures on top of the JVM.</p>
<p>Oh, and then PHP followed the trend, obviously. By the way, it is worth mentioning that Python, Perl, and Lua have had support for lambdas since the 1990s, at a time when these concepts were still considered fringe.</p>
<p>Undeniably, in the same vein, the rise in popularity of Python, Ruby, and JavaScript during the past two decades also contributed to the slow march of functional thinking into the minds of software developers worldwide. Speaking (again) about JavaScript, we have talked about Douglas Crockford&rsquo;s <em>magnum opus</em> in a <a href="/douglas-crockford/">previous article</a> of this magazine, and it was obvious to him that one of the &ldquo;good&rdquo; parts of JavaScript was, precisely, its functional programming roots:</p>
<blockquote>
<p>JavaScript is built on some very good ideas and a few very bad ones. <br>
<br>
The very good ideas include functions, loose typing, dynamic objects, and an expressive object literal notation. The bad ideas include a programming model based on global variables. <br>
<br>
JavaScript&rsquo;s functions are first class objects with (mostly) lexical scoping. JavaScript is the first lambda language to go mainstream. Deep down, JavaScript has more in common with Lisp and Scheme than with Java. It is Lisp in C&rsquo;s clothing. This makes JavaScript a remarkably powerful language.</p>
</blockquote>
<p>The quote above explains why, at the time of this writing, the latest version of the quintessential book on functional programming, <a href="https://en.wikipedia.org/wiki/Structure_and_Interpretation_of_Computer_Programs">&ldquo;Structure and Interpretation of Computer Programs&rdquo;</a>, by Abelson and Sussman, is the <a href="https://mitpress.mit.edu/9780262543231/structure-and-interpretation-of-computer-programs/">&ldquo;JavaScript Edition&rdquo;</a>. The choice of JavaScript somehow gives reason to <a href="/philip-wadler/">Philip Wadler</a>, who in 1987 <a href="https://dl.acm.org/doi/10.1145/24697.24706">argued</a> that using Scheme was probably not the best idea to begin with.</p>
<p>Lisp would certainly deserve a whole issue of this magazine, but chapter 5 of Waldrop&rsquo;s &ldquo;The Dream Machine&rdquo;, a book we <a href="/j-c-r-licklider-m-mitchell-waldrop/">reviewed</a> precisely a year ago, contains a beautiful description of its early history and its impact:</p>
<blockquote>
<p>Nonetheless, it&rsquo;s fair to say that one of Lisp&rsquo;s two greatest legacies to the art of programming was a certain style, a certain exploratory approach to pushing back the software frontiers. <br>
<br>
And the other legacy? An undeniable grace, beauty, and power. As a Lisp programmer contined to link simpler functions in to more complex ones, he or she would eventually reach a point inwhere the <em>whole program</em> was a function–which, of course, would also be just another list. So to execute that program, the programmer would simply give a command for the list to evaluate itself in the context of all the definitions that had gone before. And in a truly spectacular exercise in self-reference, it would do precisely that. In effect, such a list provided the purest possible embodiment of John von Neumann&rsquo;s original conception of a stored program: it was both data and executable code, at one and the same time.</p>
</blockquote>
<p>Since its presentation in a now legendary <a href="https://dl.acm.org/doi/10.1145/367177.367199">paper by John McCarthy</a>, Lisp&rsquo;s power and beauty have often been mentioned by pundits and entrepreneurs alike. In the latter group, we cannot avoid mentioning Paul Graham: his 2001 article <a href="https://paulgraham.com/avg.html">&ldquo;Beating the Averages&rdquo;</a> tells the story of his 1995 e-commerce startup <a href="https://en.wikipedia.org/wiki/Viaweb">&ldquo;Viaweb&rdquo;</a>, built in Lisp, a language he <a href="https://www.paulgraham.com/onlisp.html">deeply</a> <a href="https://www.paulgraham.com/diff.html">loved</a>. That article also makes a surprising connection between Lisp and the (badly named) &ldquo;Sapir-Whorf hypothesis&rdquo; of <a href="https://en.wikipedia.org/wiki/Linguistic_relativity">linguistic relativity</a>:</p>
<blockquote>
<p>By induction, the only programmers in a position to see all the differences in power between the various languages are those who understand the most powerful one. (This is probably what Eric Raymond meant about Lisp making you a better programmer.) You can&rsquo;t trust the opinions of the others, because of the Blub paradox: they&rsquo;re satisfied with whatever language they happen to use, because it dictates the way they think about programs.</p>
</blockquote>
<p>Paul Graham was not the first to make the connection to the Sapir-Whorf hypothesis, by the way: <a href="https://amturing.acm.org/award_winners/iverson_9147499.cfm">Kenneth Iverson</a>, creator of the <a href="https://en.wikipedia.org/wiki/APL_(programming_language)">APL</a> programming language, also explained this during his 1980 Turing Award lecture, <a href="https://dl.acm.org/doi/10.1145/358896.358899">&ldquo;Notation as a Tool of Thought&rdquo;</a> as follows:</p>
<blockquote>
<p>Concerning language, George Boole in his <em>Laws of Thought</em> asserted &ldquo;That language is an instrument of human reason,, and not merely a medium for the expression of thought, is a truth generally admitted.&rdquo; <br>
<br>
Mathematical notation provides perhaps the best-known and best-developed example of language used consciously as a tool of thought.</p>
</blockquote>
<p>Those of us brave enough to have written code in APL can only agree that its notation brings a whole new meaning to the word &ldquo;programming&rdquo;.</p>
<p>So it was that, standing on the shoulder of this giant called Lisp, people came up with projects ranging from <a href="https://interlisp.org/">Medley Interlisp</a> to a Lisp interpreter built <a href="https://woodrush.github.io/blog/posts/2022-01-12-lisp-in-life.html">as Conway&rsquo;s Game of Life</a>.</p>
<p>Lisp, and later functional programming languages, have enlightened software programmers to go above and beyond what commercial offerings could even dream of. They have stretched our thinking, opening doors to concurrency, mathematical breakthroughs, early artificial intelligence efforts, and the widest possible array of scientific exploration about computation.</p>
<p>Yet, already in the 1990s it was apparent that Lisp (and, to a large extent, functional programming) <a href="https://dl.acm.org/doi/abs/10.1145/192590.192600">was at risk</a> of being relegated or even of becoming extinct, and today some influencers <a href="https://www.youtube.com/watch?v=gE6nnDsh5Ck">ask themselves</a>, where did all the functional programmers go? The answer is simple: they are all among us; we are all, to a small or large degree, better software engineers because there has been a healthy breeding process between procedural, object-oriented, and functional programming languages that begat modern tools for a modern world.</p>
<p>All things considered, the most important contribution of functional languages in the modern world was a <em>certain way of thinking</em> about programming, more than just actually adopting &ldquo;pure&rdquo; functional compilers in our day-to-day jobs. Put in other words, mastering functional programming concepts fundamentally transformed the way we create software. And in the best possible way.</p>
<p>Cover photo by <a href="https://unsplash.com/@pablomp?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Pablo Martinez</a> on <a href="https://unsplash.com/photos/silver-and-red-metal-tools-S1xZ5GmpdM8?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a>.</p>
]]></content:encoded></item><item><title>Joe Armstrong</title><link>https://deprogrammaticaipsum.com/joe-armstrong/</link><pubDate>Mon, 01 Jun 2026 05:01:01 +0200</pubDate><guid>https://deprogrammaticaipsum.com/joe-armstrong/</guid><description><![CDATA[ <p>If there was a contest for the single most beloved person in the functional programming galaxy, <a href="https://en.wikipedia.org/wiki/Joe_Armstrong_(programmer)">Joe Armstrong</a> would have effortlessly won the first prize. For decades, he constantly showed the world that the principles behind functional programming were the key for resilient, concurrent, and highly available systems. And he showed it in the best possible way, which most probably made <a href="/pastor-manul-laphroaig/">Pastor Manul Laphroaig</a> very proud: with an astonishingly serious &ldquo;PoC&rdquo; called <a href="https://en.wikipedia.org/wiki/Erlang_(programming_language)">Erlang</a>.</p>]]></description><content:encoded><![CDATA[ <p>If there was a contest for the single most beloved person in the functional programming galaxy, <a href="https://en.wikipedia.org/wiki/Joe_Armstrong_(programmer)">Joe Armstrong</a> would have effortlessly won the first prize. For decades, he constantly showed the world that the principles behind functional programming were the key for resilient, concurrent, and highly available systems. And he showed it in the best possible way, which most probably made <a href="/pastor-manul-laphroaig/">Pastor Manul Laphroaig</a> very proud: with an astonishingly serious &ldquo;PoC&rdquo; called <a href="https://en.wikipedia.org/wiki/Erlang_(programming_language)">Erlang</a>.</p>
<p>That is why we have chosen as this month&rsquo;s Vidéothèque choice his presentation titled <a href="https://www.youtube.com/watch?v=cNICGEwmXLU">&ldquo;Systems that run forever self-heal and scale&rdquo;</a> at the <a href="https://web.archive.org/web/20130603195022/http://lambdajam.com/">2013 Lambda Jam</a>, a conference that featured an impressive <a href="https://web.archive.org/web/20130623055057/http://lambdajam.com/schedule/">schedule</a> with talks by <a href="https://en.wikipedia.org/wiki/Ola_Bini">Ola Bini</a>, <a href="https://www.thoughtworks.com/profiles/c/chris-ford">Chris Ford</a>, <a href="https://www.davethomas.net/biography_index.html">Dave Thomas</a> (not the <a href="https://en.wikipedia.org/wiki/Dave_Thomas_(programmer)">Pragmatic Dave</a>), <a href="https://bartoszmilewski.com/">Bartosz Milewski</a>, <a href="https://scholar.google.com/citations?user=k73mdkkAAAAJ&amp;hl=en">Adam Granicz</a>, <a href="https://www.informit.com/articles/article.aspx?p=1399235">Steve Vinoski</a>, and <a href="https://en.wikipedia.org/wiki/Gerald_Jay_Sussman">Gerald Jay Sussman</a>.</p>
<p>As you most probably know by now, Joe Armstrong (1950-2019) is mostly known for his work on Erlang, a massively concurrent and functional programming language, coupled with BEAM, the virtual machine that enabled telcos, starting in the 1990s, to serve millions of users with complex systems in the most efficient and resilient way.</p>
<p>Kids, this was 20 years before <a href="/the-age-of-concurrency/">Go</a> or <a href="/antonomasia/">Kubernetes</a> were even conceived. Erlang enabled companies to scale their services in ways that were unthinkable even by today&rsquo;s standards, running on hardware way underpowered compared to that of our modern world of 2026.</p>
<p>Joe kicked off his acclaimed book &ldquo;Programming Erlang&rdquo; (released in 2007 by The Pragmatic Programmers, with a <a href="https://pragprog.com/titles/jaerlang2/programming-erlang-2nd-edition/">second edition</a> published in 2013) with a clear disclaimer:</p>
<blockquote>
<p>In many places we&rsquo;ll be extolling the virtues of functional programming. Functional programming forbids code with side effects. Side effects and concurrency don&rsquo;t mix. You can have sequential code with side effects, or you can have code and concurrency that is free from side effects. You have to choose. There is no middle way.</p>
</blockquote>
<p>And he goes on to explain on page 44 (mind you, this was written in 2007) what &ldquo;functional&rdquo; means in this context:</p>
<blockquote>
<p>Erlang is a functional programming language. Among other things this means that funs can be used as arguments to functions and that functions (or funs) can return funs. <br>
<br>
Functions that return funs, or functions that can accept funs as their arguments, are called <em>higher-order functions</em>. We&rsquo;ll see a few examples of these in the next sections.</p>
</blockquote>
<p>I stress the fact that this was written in 2007 because merely 20 years ago, as we were entering the &ldquo;plateau of productivity&rdquo; in the <a href="/the-hype-cycle-of-oop/">hype cycle</a> of Object-Oriented Programming, we were also witnessing how Twitter (the original name of a decadent social network still active as this article hits the press) was suffering with &ldquo;fail whales&rdquo; shown on its home page, while millions of users were trying to read the tweets on their (not yet algorithm-driven) feeds. The time was ripe for a new paradigm… but apparently, unbeknownst to the Twitter team, it already existed.</p>
<p>Interestingly, the WhatsApp developer team knew exactly that they needed something else to create a system potentially usable by billions of simultaneous users, so they chose Erlang, and boy did that work well. More on that later.</p>
<p>In his 2013 conference talk, Joe Armstrong started with some simple observations: the real world is parallel. Boom. It turns out that Erlang processes are the perfect way to model such a world: they can be thought of as a group of people communicating by message passing.</p>
<p>Let us remember <a href="https://lists.squeakfoundation.org/pipermail/squeak-dev/1998-October/017019.html">what Alan Kay said</a> about messaging in 1998:</p>
<blockquote>
<p>The big idea is &ldquo;messaging&rdquo; &ndash; that is what the kernal of Smalltalk/Squeak is all about (and it&rsquo;s something that was never quite completed in our Xerox PARC phase). The Japanese have a small word &ndash; ma &ndash; for &ldquo;that which is in between&rdquo; &ndash; perhaps the nearest English equivalent is &ldquo;interstitial&rdquo;. The key in making great and growable systems is much more to design how its modules communicate rather than what their internal properties and behaviors should be.</p>
</blockquote>
<p>So here we have a programming language that allows you to model a world with certain characteristics that Joe describes around minute <a href="https://youtu.be/cNICGEwmXLU?t=330">05:30</a>: many computers distributed all over the place, working concurrently, detecting their own failures and repairing them as soon as possible, and even featuring a radical concept called live code upgrades.</p>
<p>Sounds familiar? Any parallels with Kubernetes are just a coincidence. In Erlang, there is no such thing as an atomic update of the &ldquo;stop it, upgrade, restart&rdquo; kind (<a href="https://youtu.be/cNICGEwmXLU?t=409">06:50</a>): Erlang applications are continuously partially upgrading themselves whenever needed.</p>
<p>Needless to say, this was beyond impressive in the mid-1990s, but <a href="/issue/issue-024-java/">Sun</a> had a bigger marketing budget than Ericsson. Insert sad face emoticon here.</p>
<p>Erlang was designed from the ground up for &ldquo;5 nines reliability&rdquo; (<a href="https://youtu.be/cNICGEwmXLU?t=429">07:10</a>) because of a simple observation: it is much better to design a system for 10 million users and scale it down to 10,000 than to scale it up from 10 to 10,000. The result is that by 2013 there was a 50% chance that smartphones went through Erlang to talk to the mobile Internet.</p>
<p>But Erlang is just a piece of the whole architectural cake, albeit a critical one. Joe goes on to elaborate on the patterns required for system consistency and fault tolerance, distributed consensus (<a href="https://youtu.be/cNICGEwmXLU?t=1416">23:36</a>), and the evolution from Lamport&rsquo;s <a href="https://en.wikipedia.org/wiki/Paxos_(computer_science)">Paxos</a> to Ongaro&rsquo;s and Ousterhout&rsquo;s <a href="https://en.wikipedia.org/wiki/Raft_(algorithm)">Raft</a>. He also mentions six rules for fault tolerance (<a href="https://youtu.be/cNICGEwmXLU?t=1769">30:00</a>), applicable to any massively distributed system running on your nearest Kubernetes cluster nowadays: process isolation, concurrency, failure detection, fault identification, live code upgrade, and stable storage.</p>
<p>Legendary computer scientist <a href="https://en.wikipedia.org/wiki/Jim_Gray_(computer_scientist)">Jim Gray</a> wrote a widely quoted paper in 1986 titled <a href="https://pages.cs.wisc.edu/~remzi/Classes/739/Fall2018/Papers/gray85-easy.pdf">&ldquo;Why Do Computers Stop and What Can Be Done About It?&rdquo;</a> where he said:</p>
<blockquote>
<p>The top priority for improving system availability is to reduce administrative mistakes by making self-configured systems with minimal maintenance and minimal operator interaction. <br>
(…) <br>
As with hardware, the key to software fault-tolerance is to hierarchically decompose large systems into modules, each module being a unit of service and a unit of failure. A failure of a module does not propagate beyond the module.</p>
</blockquote>
<p>Now you understand why your Kubernetes <code>Deployment</code> YAML contains a readiness and a liveness probe, for example. You are welcome.</p>
<p>Towards <a href="https://youtu.be/cNICGEwmXLU?t=2749">minute 46</a> of the video, Joe goes on to talk about Erlang in detail, enumerating some success stories: <a href="https://en.wikipedia.org/wiki/Mnesia">Mnesia</a>, <a href="https://en.wikipedia.org/wiki/Apache_CouchDB">CouchDB</a>, <a href="https://en.wikipedia.org/wiki/Riak">Riak</a>, <a href="https://en.wikipedia.org/wiki/Ejabberd">ejabberd</a>, <a href="https://en.wikipedia.org/wiki/RabbitMQ">RabbitMQ</a>, and, yes, of course, WhatsApp, snapped up by Facebook for a hefty 20 billion dollars of pocket money. And then he goes on to discuss the future of Erlang as seen from the perspective of 2013: <a href="https://en.wikipedia.org/wiki/Elixir_(programming_language)">Elixir</a>, a programming language based on BEAM and OTP but offering an admittedly much friendlier syntax (inspired by <a href="/issue/issue-089-ruby/">Ruby</a>) with interesting metaprogramming possibilities.</p>
<p>Watch this month&rsquo;s Vidéothèque entry, &ldquo;Systems that run forever self-heal and scale,&rdquo; by Joe Armstrong, <a href="https://www.youtube.com/watch?v=cNICGEwmXLU">on YouTube</a>. Continue binge-watching &ldquo;Erlang: The Movie,&rdquo; a 1990 short nowadays available on <a href="https://www.youtube.com/watch?v=xrIjfIjssLE">YouTube</a> and the <a href="https://archive.org/details/ErlangTheMovie">Internet Archive</a>, showing a demo of a bug-fixing session on a live Erlang system. Let us repeat for the people in the back: <a href="http://lambda-the-ultimate.org/node/197">1990</a>.</p>
<p>Cover snapshot chosen by the author.</p>
]]></content:encoded></item><item><title>Guy Steele &amp; Gerry Sussman</title><link>https://deprogrammaticaipsum.com/guy-steele-gerry-sussman/</link><pubDate>Mon, 01 Jun 2026 05:00:02 +0200</pubDate><guid>https://deprogrammaticaipsum.com/guy-steele-gerry-sussman/</guid><description><![CDATA[ <p>Imagine a world in which two people take the best ideas from programming languages, and create an interpreter for their own programming language. Then they demonstrate that most of the features in that programming language&mdash;indeed, in <em>all</em> programming languages&mdash;can be constructed out of just three features of their interpreter: lambda application, conditional execution, and variable assignment. Then, they show that variable assignment is the wrong way to think about variable assignment, and show that their interpreter points to the most efficient way to make language compilers, and made a compiler for their interpreted language to show how good that could be. Then, imagine that they share this knowledge with the world, for free, through a series of memos.</p>]]></description><content:encoded><![CDATA[ <p>Imagine a world in which two people take the best ideas from programming languages, and create an interpreter for their own programming language. Then they demonstrate that most of the features in that programming language&mdash;indeed, in <em>all</em> programming languages&mdash;can be constructed out of just three features of their interpreter: lambda application, conditional execution, and variable assignment. Then, they show that variable assignment is the wrong way to think about variable assignment, and show that their interpreter points to the most efficient way to make language compilers, and made a compiler for their interpreted language to show how good that could be. Then, imagine that they share this knowledge with the world, for free, through a series of memos.</p>
<p>That world that you just imagined? We live in it. Meet Guy L. Steele, Jr., and Gerald J. Sussman, two of the luminary thinkers from the Massachusettes Institute of Technology Artificial Intelligence Lab. This is the first go around the AI hype cycle, back when computers were routinely called <a href="https://www.sciencemuseum.org.uk/objects-and-stories/thinking-machines-stories-history-computing">thinking machines</a> but before people even <a href="https://machinelearning.apple.com/research/illusion-of-thinking">pretended that computers were doing any thinking</a>.</p>
<p>However, it is really not that valuable to distinguish between AI computing and non-AI computing, because <a href="https://www.sicpers.info/2026/03/on-thinking-machines/">all computation is an emulation of intelligence</a>. The AI research community is best thought of as an advanced computational techniques community that began life exploring computational methods to understand thought, and that is where this story begins. The person who coined the phrase &ldquo;Artificial Intelligence&rdquo; was John McCarthy, and for no more highbrow reason than that he thought if he presented his work in symbolic computation techniques as &ldquo;cybernetics&rdquo; then he would end up having an argument with Norbert Weiner, and if he called it &ldquo;information processing&rdquo; then the argument would be with Claude Shannon. Both of these intellectual giants were too scary to argue with.</p>
<p>McCarthy consulted for IBM on <a href="https://dl.acm.org/doi/10.1145/800025.1198360">the addition of a List Processing library to FORTRAN</a>, but preferred to use an algebra based on symbolic expressions so created his own programming language, LISP. For the first few years LISP users had to execute their programs by hand using pencil and paper, until Steve Russell noticed a huge opportunity. The language includes a neat trick called <code>eval</code> which interprets a LISP expression as a LISP program, and Russell realised he could implement <code>eval</code> in machine language (by punching holes into punchcards) on the IBM 704. Thus is was, with the creator of LISP and the creator of AI research being the same person, that LISP became the preferred programming language of AI researchers.</p>
<p>Fast-forward to the mid-1970s, and the MIT AI Lab (counting McCarthy among its alumni, of course) used a LISP dialect called Maclisp: nothing to do with the later personal computer model, but named after the Project on Mathematics And Computation that hired the original AI group (including McCarthy, of course). Maclisp&rsquo;s innovation over LISP is the use of <a href="https://softwarepreservation.computerhistory.org/LISP/MIT/Moon-MACLISP_Reference_Manual-Apr_08_1974.pdf">value cells</a> to associate objects with symbols, where LISP maintained a list of associations that it scanned through to find the object. Two of the AI lab members&mdash;the heroes of this story&mdash;wanted to explore the <a href="https://dl.acm.org/doi/abs/10.5555/1624775.1624804">Actor model</a> of computation (another product of the AI research galaxy), and did so in their own, minimalist LISP interpreter, which they wrote (inevitably) in Maclisp.</p>
<p>They borrowed a neat idea from the ALGOL programming language: block structure, and lexical scope. A variable (or function, or label) can be declared inside a block, in which case it is <em>local</em> to the block: it only exists while that block&rsquo;s in scope. If the variable has the same name as an existing variable from another scope, it <em>shadows</em> that variable, replacing uses of variables of that shared name with itself. But only within the block.</p>
<p>Steele and Sussman documented this Lisp interpreter, which they called <a href="https://www.scheme.org">Scheme</a>, through a series of AI Memos <a href="https://research.scheme.org/lambda-papers/">now sometimes called the LAMBDA papers</a>, after the recurring form &ldquo;LAMBDA: the Ultimate <code>X</code>&rdquo; in their titles. In <a href="https://dspace.mit.edu/entities/publication/a40a9ba3-619a-4495-b357-5c2eb2442066">LAMBDA: the Ultimate Imperative</a>, they show that lambda application can model almost every feature of an imperative language (using ALGOL in their case, but the same would apply to FORTRAN, C, Swift, Rust, or your favourite poison). Steele then issued a correction a few months later, <a href="https://dspace.mit.edu/entities/publication/4b273252-5dbe-488f-891b-0c63eaaf25a1">LAMBDA: the Ultimate Declarative</a>.</p>
<p>Whoops! Did we say that lambda was the ultimate imperative? What we meant was that function calling is the ultimate imperative if you think of a function call as a <code>GO TO</code> statement with a message alongside it (sending messages? That is the actor model achieved!); what lambda gives you is a way to rename variables, defining an environment in which your fancy <code>GO TO</code> operates. That is a powerful idea in itself, because it means you do not have to mess around copying values into registers or onto the stack whenever you call a function; you just associate the new name with the existing value. He further explored this idea in <a href="https://dspace.mit.edu/entities/publication/77b3eea1-50be-4e3f-b578-264484ee0f1a">Lambda: the Ultimate GOTO</a>.</p>
<p>Eventually, in 1979, the two authors published <a href="https://dspace.mit.edu/entities/publication/e70f4d48-b51c-4b29-996f-44ecb22441a4">LAMBDA: the Ultimate Opcode</a>, in which they design the LISP machine: a hardware implementation of a state machine that evaluates LISP expressions, along with operations that work efficiently with the linked data structures native to the language.</p>
<p>Reading this series of AI memos in 2026, which are written in a straightforward, tutorial style, gives one first the feeling that understanding the complexity of computers and programming languages might not be so difficult, after all. Then, one remembers that their current problem involves multiple programming languages and script files and YAML files and TOML files, and the effect is more like being Charlton Heston looking up at the Statue of Liberty.</p>
<p>Cover photo by the author.</p>
]]></content:encoded></item></channel></rss>