Lua as a practical "soft-bedrock" language
The folks behind the Lua programming language maintain a page detailing the release dates of all released versions of the language. My favourite thing about that page is that right at the top there is a graphical timeline, with years marked below the line and a little vertical marker above the line at the appropriate place for each release. This timeline makes it immediately obvious at a glance that Lua is doing something all software projects ought to aspire to but very few actually manage to achieve: it is slowing down.
Official Lua version history page
From Lua 1.0 in 1993 through to Lua 5.5 at the end of last year, there have been 16 public releases of the language, corresponding to 15 inter-release intervals. The mean of first five of those intervals, at the beginning of the languages life, is 246 days - less than a year, with two releases coming out in both 1995 and 1996. For the middle five intervals, the mean is nearly double that, at 466.8 days, with more than a year between releases (although it seems like there was a brief spell where releasing once per year in July might have been an explicit norm, with 3.0, 3.1 and 3.2 being released in July of '97, '98 and '99, respectively). Moving to the five most recent releases, the mean inter-release interval more than triples to 1658.2 days, with more than four years between every release! When the idea for this post first entered my head, probably in 2024 or maybe 2023, Lua 5.5 had not yet been released and I really held out hope that the next inter-release interval to be observed might be some kind of record breaker, perhaps over six years, but actually the interval between 5.5 and 5.4 turned out to be about the same as between 5.3 and 5.5, both being about five and a half years apart.
I also had it in my mind when this post first started to form there that I'd do similar analyses for both Go and Python and would find, in an internal-narrative-conforming way, that these languages were either maintaining a steady pace of development or "even better" (for me, rhetorically) that they were in fact accelerating, speeding up out of control. But in actual fact, both those languages are slowing down too, although just barely. There have been 26 public releases of Go, giving us 25 inter-release intervals. These intervals are extremely regular, suggesting a planned release schedule - of the 25 intervals, fully 16 of them are between 180 and 190 days. But they are still slowing down, with the means of the first 8 intervals being 178.5 days, the middle 9 intervals 185.3 days and the most recent 8 intervals 223.25 days. Compared to Lua, where the intervals nearly double and then more than triple, this is a pretty meagre slowdown, although in fairness I ought to note that the most recent interval of 411 days represents a substantial increase, being the first and only interval over a year long. The story for Python 3 is pretty similar, with 14 inter-release intervals, the means of the first 5 being 365.6 days (almost precisely one-release-per-year!), the middle 4 being 462.25 days, and the most recent 5 being 495 days.
Official Go release history page
Official Python version status page
One might argue that these comparisons are all rather pointless, there being no guarantee that the actual amount of substantial change between consecutive minor versions is remotely comparable across languages, or that all languages pay the same amount of attention to backward compatibility, and there also being real logistic advantages to fixed and predictable release schedules. All true! But impressionistically, these numbers really match my subjective experience that Go and probably more so Python do not feel at all like languages which are slowly crystallising toward some kind of fixed final form.
When mozz's JetForce Gemini server was released in 2019, I somehow ended up reading some of its code before knowing that it was in fact written in Python. My first impression was that it was written in some new upstart language I'd never heard of which had clearly been very closely inspired by Python but had some kind of typing system with a bunch of funky extra syntax. I was shocked to discover very shortly later that it was, in fact, just written in modern idiomatic Python - a type hinting system was introduced in 2015 in 3.5. That's a hell of a change to introduce to a popular and successful decades old language, especially one which already went through a long and painful transition between major versions when a lot of big changes were supposed to be made! But it's not just that modern Python code is literally unrecognisable to long-time users (I learned Python with 2.4, circa 2000), working old code needs frequent maintenance as well. I have already had to update AV-98 once due to Python dropping support for the standard library's cgi module, and I think I still haven't dealt with it throwing deprecation warnings about some part of the ssl module.
The jetforce Gemini server, one of the oldest and still maintained!
When I somewhat recently returned to working on Molly Brown after a pause of I guess a few years, I was stunned to discover that I couldn't simply `cd` into my working tree and `go build` anymore, without first creating a .mod file first. This is less of a change in the language itself than in the associated tooling, but I'm really not much more happy about that kind of change either, in fact it might even be worse (and Python is certainly guilty of having an ever-changing tooling ecosystem as well, as anybody who has tried to package a Python project will tell you). I have less immediately ready-to-cite examples of changes in the Go language itself causing me headaches, although I will note that in version 1.18 the language apparently acquired some kind of support for generics, something which was in very popular demanded from the language's early days but which the designers - who I used to consider kindred spirits by virtue of their very explicit statement that the Go project included a "cultural agenda of radical simplicity" - always firmly ruled out of consideration on the grounds of implementation complexity. I don't know if someone came up with some kind of brilliant scheme for implementing generics which was acceptably lightweight or if the designers merely caved in to popular pressure, but either way Go has changed from being a language which deliberately doesn't have generics for a principled reason to being one which has them anyway.
Please understand my complaint here is not about the specifics of these changes, I'm not saying that type hinting is bad or that generics are bad and that Python and Go would have been better off without them. My complaint is that changes of this magnitude happening in minor releases of languages over a decade old makes those languages feel amorphous and lacking in core identity. It makes it hard to believe that their development will ever get to the point of slowly cooling off and solidifying. Who knows will be added to either one 5 or 10 years from now? This changes learning to read and write code in these languages from a skill you acquire once and then spend many years slowly perfecting to being something you have to keep running on a treadmill to maintain. Nobody would ever bother learning to play the piano or to paint watercolours if we kept tweaking our scales and musical notation systems or coming up with radically different brushes every five years. You really can freeze the foundational concepts and the essential tools for a given human endeavour without doing anything to unduly restrict their scope for creativity and expression, and that endeavour can still be a satisfying and worthwhile thing to devote your entire life to the practice and mastery of. Maybe this approach is not appropriate in the environments of industrial capitalism, but true personal computer hackers ought to demand it, in defence of their own sanity if not the environment! This is not a whimsical and impractical ideal. It is immensely practical to be able to solve a problem once and have the solution keep working without change for as long as the problem itself remains unchanged.
One might object that the comparison between Lua and these languages is unfair, because Go and Python both come with large and powerful standard libraries, while Lua is much more minimalistic. This is not without truth, and in fact Python's changes to its standard library have caused me more grief than its changes to the language itself. But Lua's slow-and-getting-slower pace of development largely extends to its surrounding ecosystem as well. The popular "Penlight" library, which adds a lot of Python-inspired utility functions for string manipulation and similar generic programming tasks, made a new release in January of this year, mostly just to add support for Lua 5.5. The last release before that had been over a year and a half ago, and the one before that took similarly long. There's a similar but smaller and simpler library called "Microlight", which literally hasn't been touched in 11 years. I have used it much more recently than that without problems.
Microlight, "a little library of useful Lua functions"
I would go so far as to say that Lua is probably a language well-suited to permacomputing (and indeed this is the reason that all of my OFFLFIRSOCH projects so far have been written in Lua), not just because it moves very slowly but also because it is highly portable by design. This will perhaps be a controversial opinion. In an influential essay on permacomputing, Viznut wrote "asking what is the most suitable programming language for permacomputing is a bit like asking what is the most suitable plant for permaculture – the entire question contradicts itself", and I think this has taken on a kind of orthodoxy. I must profess to having never understood or agreed with this sentiment. Obviously there is no one-size-fits-all universal answer to this question, and obviously there is resilience in diversity, but neither of those are the same thing as the question being self-contradictory. Certainly there must be languages which are plainly unsuitable, by virtue of being resource intensive, difficult to port, constantly and unpredictably changing and with toolchains which are also constantly and unpredictably changing, etc. Doesn't this make languages without these traits "more suitable" at the very least? The permacomputing wiki lists "build on solid ground" as a permacomputing principle, and while the article on "bedrock platforms" is mostly focussed on hardware, it does talk a little bit about Lisp at the end. I would argue that the notion of a "bedrock language" is perfectly coherent. I wouldn't say that Lua ought to be a textbook example of one - it is obviously "boggier" than ISO C or Z80 assembly or various FORTHs and Lisps. However, it's much faster and easier to write than good C or assembly, and it's, well, a lot more "normal" than FORTH or Lisp, and while it isn't super bedrocky, it's clearly much closer to that ideal than many, perhaps most, popular mainstream languages. Maybe it's the bedrockiest language which is still very practical for real world use (as evidenced by its wide adoption in the games industry)? I feel like it has to be in the running, at least.
Viznut's "Permacomputing Update 2021"