A cabbage moth

Jun's Alcove

Index Journal Projects Exhibits About

Ecological Programming

I wanted to take some time to write out my thoughts around writing software, and the very important reasons to conceptualize and realize more efficient, small software. That said though, this is not an argument for "just use <insert your favourite C-like here> and a terminal", this is an argument for improving general knowledge within the industry.

The Problem Statement

The modern world of software is one that exists solely due to the very hard work of hardware engineers. Computers have gotten so unbelievably fast that the prevalent idea is to ignore efficiency until it is a business concern. This state of software is frankly absurd to me. The lack of efficiency in modern software likely has a far worse impact to energy usage globally than people want to admit.

So in this blog post I want to discuss some possible, balanced solutions to the systemic lack of efficiency considerations in the software industry.

Simple Software vs Small Software

I want to make sure I explain this distinction. Simple software is not necessarily small, and vice-versa. You can write a simple calculator that takes multiple gigabytes of memory, and takes a full second per operation. Likewise, you can write an entire operating system kernel that fits within 20MB, and runs almost anywhere (see: the Linux kernel).

Things like the JVM, for how great it is, wastes power. Languages like Ruby, Python, Perl, PHP, etc all waste power in the name of "programmer convenience". What I want to mention in this article are languages and technologies that I think find a proper balance between programmer expressiveness and convenience, while maintaining a small and efficient footprint at runtime.

Some Expectations

Each solution will not be able to cover 100% of software use cases. That said, I will be prioritizing userspace applications instead of kernel-space or RTOS applications. The latter issues have readily available and powerful tooling including C, Ada, Rust, Zig, and more. Furthermore, this will not be accounting for the modern web landscape. This is because I am of the belief that the web centric world we live in is antithetical to ecological, efficient programming. There is no saving an interlocked system of interconnected, enshittifying systems.

Furthermore, plenty of the existing userspace applications within Windows and Linux are very stable, with no need or reason to replace. GNU coreutils or Busybox are fast, stable POSIX-compliant applications that are in no need of being replaced. The problem statement this blog posts deems to cover is for new programming, and building on top of the solid baseline created by the past. Because while I understand those who are happy to live within a pure terminal ecosystem and use the backbone as the entire computer, that is not how modern computing is being used at large.

As such, each sub-heading after this will attempt to answer the following question: What is a possible tech stack to use for 80% of software problems?

Modern C

I want to start the list of options with one I consider quite weak. As someone who has loved and defended C for a very long time, I have come to accept that most people aren't willing to overcome its shortcomings. And more than that, I understand that the need to overcome shortcomings of a language is a limitation of the language, not the environment it lives in.

C comes with so much legacy attached to it that you cannot even be certain what the bit-width of a simple integer is. I won't get into the world of implementation defined behavior, architecture dependant settings, etc. What is to be said is that C does not provide the tooling to write robust, efficient software. In fact, for anything not purely technical in nature (such as a GUI application), its limitations can cause a severe loss of efficiency.

So what about the modern C-like trend? Well, I think they are improvements. But between Odin (my personal favourite), Zig, Hare, etc; There are none with enough improvements to really warrant its adoption within the problem statement. Perhaps they will effectively supplant C in RTOS and kernel spaces, but userspace needs another tool.

JavaScript

JS is, in my opinion, a worse option than C for userspace. It is a flaky, dynamic, inconsistent language that has been carried in popularity by the web itself. To add onto this, JavaScript must rely on things like Electron, and the V8 runtime in order to operate. These are massive, complex, and largely unnecessary systems.

While some people may argue for TypeScript, it will suffer from all the same runtime limitations such as its single-threaded model, overly complex runtime environment, and runtime error handling. At the end of the day JavaScript is a bad tool that has become so ubiquitous that an entire ecosystem formed to try to turn it into something acceptable. If the language itself cannot be used without pulling in advanced and complicated runtimes and libraries, it is a bad tool.

Golang

Go is a programming language I personally detest. It is designed to be simple at the cost of programmer expressiveness and basic features. Its GC is still largely untunable and the lack of expressiveness causes less efficient code to be written by default. This is the reason why Go is frequently touted as a way to write "simpler" software, because writing anything beyond a simple application in it is a tiresome, frustrating process that leaves you with a largely inefficient and problematic codebase. While this does provide itself with a niche where it may be the ideal tool, it struggles beyond that.

Go is not a solution to more efficient programming, it is a solution created at Google to solve the issue of new hires not having the prerequisite knowledge to use more advanced language tools. This is an admission from Rob Pike himself.

Rust

Rust is a very powerful language, with great language features taken from all paradigms of programming. Its strong typing reminiscent of Haskell or ML, and the allowance for more imperative programming in the name of familiarity. Rust, in my opinion, is a strong contendor for a better userspace technology. This does stand in contrast to my personal opinion of Rust, which is that its syntax is largely inflexible, unergonomic, and convoluted. These are however personal gripes, and should be oriented as such.

Its main drawback is its very inefficient compiling strategy, and times. That said however, I do not consider a more expensive compilation a large drawback. While it lowers efficiency of development, it allows the additions of features that can drastically improve the runtime efficiency of the same application.

Scala Native

Scala is my favourite programming language, and I do not keep this as a secret. It is a highly flexible, versatile, and expressive language that allows the programmer to apply their knowledge as needed to write code how they need. Scala Native is naturally a highly valued contender to me personally as a result. While it shares the same drawback as Rust—expensive compilation, added by the requirement of a JDK and Scala JVM runtime to compile—It gains a lot of power over something like Rust by allowing the programmer to adjust to the needs of the task. It ships with a powerful GC—Immix and its concurrent counterpart—as well as allows the programmer to use direct memory management as required. It also provides Zones in order to provide a semi-automatic memory management model independent of the GC. This flexibility of memory is only mirrored by D, but it comes with all the power of the Scala programming language.

Scala as a language gives power to the programmer in a way no other programming language truly does, and with that comes a powerful tool that when taken off of the JVM enables it to solve most any problem. And while I am not against the JVM itself; It is a large and unyieldy runtime that should not be used across billions of devices unilaterally, and the Scala Native runtime gives Scala the legs it needs to move away from it for the userspace world.

Conclusion

At the end of the day, there will never be a unified tech stack. While my bias is obvious and clear, as I intended it to be, you may disagree with me. Such a disagreement is welcomed. If you love Golang, use it. There are times a simple tool is ideal. If you want to use Rust, use it. I simply wanted to broadcast my opinions on the matter into the void, and for me expressiveness of programming is the most important aspect. Being restricted by your tool is not the benefit one may think it is. An example is simple: A short-running application may not need to waste time cleaning up memory, while a long-running one will. Rust hates, but supports the former use-case, while C can easily invert that anthropomorphized opinion.

The main thing I want more people to understand as programmers is this however: The web, and the modern software mindset, is the antithesis of efficient software. Moving back towards desktop applications gives us the flexibility to write more efficient, smaller applications. While I haven't explained my thoughts on the web specifically in detail here, I will in a future blog post.

But please: Write efficient software. We need to be thinking about how we impact the environment on all levels. Yes, cattle and oil are the primary contributors. Yes, the bottom 50% of wealth contributes the same to climate change as the top 1%. But if you read this entire post, you're not in the bottom 50%. You're at least in the top 50%, which contributes very heavily to climate change as well. So please, do what you can.

Another moth