Radiant Log #001

On platforms and languages
Alexis Sellier
March 13, 2025

I’ve been pondering how code for the Radiant will be written, or rather in what language. After the bootstrapping phase, where I’ll use my regular Linux environment to develop a first version of the new platform, I’ll need to move development to the Radiant itself; requiring tools and a compiler that run natively on it. This transition from host to target presents interesting technical and philosophical challenges I’d like to address sooner rather than later.

There are roughly two paths forward: (1) porting an existing compiler toolchain to the new platform, or (2) building a new one from scratch. Though I originally considered porting a C compiler such as lcc to the target platform, I no longer consider C a good default for system software.

Another approach that seemed reasonable was to implement a compiler for a subset or variant of C, by omitting features that are unnecessary, while adapting existing features to better fit the new platform. This approach was taken by Ken Thompson and the rest of the team at Bell Labs when designing the compiler suite for the Plan 9 operating system. Their C implementation deliberately excluded certain language features while adapting others to better fit Plan 9’s design philosophy. It’s also the approach Terry A. Davis took for TempleOS with HolyC. In both cases, the C language was improved for the specific platform, allowing for a more coherent experience between the language and the underlying system.

Beyond technical considerations, the language choice speaks to deeper questions about the platform itself. The programming language is the heart of a computer platform; it defines what can be expressed and what is permitted. Like any core component of a greater system, it should reflect the values of the greater whole, whether it’s simplicity, control or approachability.

Through careful trade-offs and design, programming languages create affordances that shape the software development process towards specific solution spaces. A system language designed for its target platform is thus one that makes it easy to produce good solutions for that platform, and hard to produce bad solutions. Here, what is meant by “good” and “bad” goes beyond measurable outputs, and is about whether a solution is coherent with the target platform. This coherence starts with system architecture and extends all the way to the user experience of the programs developed using the language.

This coherence between language and platform isn’t merely an academic concern, but fundamental to system design, as Carl Sassenrath wrote in 1997:

“Why a language? Because I believe that the core of computing is not based on operating system or processor technologies but on language capability. Language is both a tool of thought and a means of communication. Just as our minds are shaped by human language, so are operating systems shaped by programming languages. We implement what we can express. If it cannot be expressed, it will not be implemented.” – Carl Sassenrath

Sassenrath was the chief architect of the Amiga computer’s operating system in the 1980s. He created the Amiga’s preemptive multitasking kernel that was decades ahead of its time, and later went on to design the REBOL programming language.

This philosophy of language as the foundation of computing systems is mirrored in the work of other computer scientists. I’ve lately been fascinated by the work of Niklaus Wirth, the Swiss computer scientist who invented Pascal, Modula and Oberon. Wirth was particularly interested in teaching computer systems and in their ability to be understood. Wirth’s idea was that good software is software that can be comprehended in its entirety by a single person.

This principle of comprehensibility underpins most of his work, but in particular the Oberon System:

“Project Oberon is a design for a complete desktop computer system from scratch. Its simplicity and clarity enables a single person to know and implement the whole system, while still providing enough power to make it useful and usable in a production environment.”

Surprisingly, the entire Oberon System, including the compiler, a graphical user interface, a text editor, a graphics editor, keyboard, mouse and display drivers consists of only around twelve thousand lines of code in the Oberon language. This remarkable achievement was possible through meticulous attention to design, a careful selection of abstractions, and ruthless elimination of unnecessary complexity. Wirth demonstrated that by taking control of the entire stack; from language to operating system, even down to the target CPU instruction set, which he designed alongside the rest of the system, you could build a complete system with a fraction of the code used by modern systems. This idea of hardware and software being designed together is sometimes called holistic engineering; I’ll be writing a lot more about it.

What’s particularly noteworthy is that the Oberon System wasn’t merely an academic exercise; it was actively used at ETH Zürich and other universities as a complete computing environment for both education and research throughout the 1990s.

Wirth documented this journey in his book about the design of the Oberon System. Sadly, he passed away in 2024.

The principle of comprehensibility resonates strongly with me. It’s one of the core tenets underpinning the Radiant project. One of the reasons for starting Radiant is to get away from the accumulated complexity and incomprehensibility of mainstream software.

For these reasons, I decided it was not only possible but desirable to start the design of this new platform from the programming language up, using no third party code beyond the bootstrapping phase. The path forward is now clear.

In the next entry, I’ll discuss my approach to designing and implementing the language that will become the foundation of the Radiant platform.