Skip to content

thezipcreator.srht.site

Linlu - A malleable computing environment.

Created 2/25/2025, 6:50:51 PM

Linlu* is an idea for a shell and UI toolkit designed around malleable software philosophy. The intent is to give the user the ability to compose independent programs, perhaps written by different people, in a way that does not require intimate knowledge of programming or of the machine.

NOTE: None of the ideas presented here are currently implemented (as of the writing of this article). While an implementation is being worked on, it is most likely going to be a while before a basic working prototype is available.

Table of Contents

1. Prelude

There is a large problem in the world of GUI applications—We build all of these independent apps, but none of them are made to interact with eachother. Each app is a largely independent tool, isolated from the rest of the environment and from other apps. For example, think about what it takes to send data from one application to another. Typically, this requires us to save the data to a file, picking where we want to put this file, then go to the other program, navigate to the file in that program, and open it. And this is even if the two programs share file formats that are interoperable! If they're not, then we can try to build a converter so that one file can be made to be used in the other program, (which adds yet another step to our process), or if that's not possible then we're just out of luck. And even when the file format is supported, it is still annoying to have to export from one program to another every single time we wish to use it in the other program, especially if we're doing this often.
And this is assuming the data we want is even exportable from the program, which is not guaranteed to be true. For example, say we were making a speedruning split program; this is a program which is set up with a number of achievements (or splits) to do in a video game (e.g. "Beat Level 1", "Finish the Prologue", "Skip the last Boss Fight", etc.), and we want the program to automatically recognize when these happen. To do this, these tools inspect the raw memory of the game and look at specific addresses to figure out when a certain split should occur.[1] Needless to say, this is a horrible solution; this requires reverse-engineering the game to figure out what exact RAM addresses are used for what things, and this can easily change from version to version.
So with those problems laid out, what can we do? Well, we should stop designing our programs to be isolated islands of code. Instead, programs should interact with eachother. I'll go even a step further—Applications should be collections of independent, smaller tools that do one task and do it well. In addition, these tools should be easily modifiable and composable by the user—Sure, an average user might not be able to implement an entirely new thing, but they should be able to hook up and connect existing functionality from multiple programs together.
I'll note that a lot of this is possible in CLI applications; just pipe the output into the input of another. But for whatever reason, we lost our way when developing GUIs, and it has never come back. There has been a few attempts, such as Smalltalk, but pretty much all mainstream desktop environments feel stuck in this rigid separation between apps. Linlu is an attempt to rectify this (although, admittedly, is unlikely to succeed outside of a small niche).

2. Objects

An object is a small collection of data and functionality. That data is stored in fields, which have a type and a value. The type of a field is what kind of data is stored in it, and the value is what data that is. The type also has a capability, which determines what it is allowed to do with the data in it. For example, if we have a field with the type Text, that means that it is some string of text, and that the object can both read and write from that text. But a field of Text read can only read from it, and a field of Text write can only write to it. Object fields may be exposed, which means that the user can see them, or hidden, which means that only code can see them. Most fields should be exposed, unless there is a specific reason to hide them. Fields that are exposed may be linked to eachother, meaning that the field's value is shared between the linked fields. This can be done within the same object, or across multiple objects. The functionality of the object is stored in methods, which have a return type (the type of value created by the method), and parameters, where each parameter has its own type. If these are exposed, then the user may trigger the method at any time. Methods may also be setup to be triggered every time a certain field is changed.
To give a concrete example, say we have a simple "Text Editor" object. This exposes a field called "text" which is of type Text. Then, we have a "Word Counter" object that has two exposed fields: "Text" of type Text read, and "Word Count" of type Integer write. When we put text into the "Text" field, Word Counter automatically detects that, calculates the word count, and writes it into "Word Count". So, we could then link the "Text" field of our Text Editor object into the "Text" field of the Word Counter object, and that creates a live-updating word count o the text we're writing in our text editor.
Objects belong to classes, which determines exactly what fields and methods it has. You can think of a class like a model for what an object should be. If we think of an object like a specific product, for example, then the class is what type of product it is. If I have an Moto G Play phone, for example, then that specific phone (mine) is an object in this anology, while "Moto G Play" is the class of that object. And if you have an iPhone 10, then that's an object of an entirely different class. These classes may be used as the types of fields too, meaning you can have objects that contain other objects. Classes themselves may be hidden or exposed. If a class is exposed, then objects of that class may be created by the user.
The general idea is that any field exposed by any object can be linked with any other field exposed by any other object, allowing for maximum extensibility of programs written, and making programs be as reusable and non-isolated as possible.

3. Modules

A module is a collection of classes, with a UUID, and a version number. The version number takes the form of a quadruplet of numbers, using Epoch Semantic Versioning. Multiple versions of the same module may be installed at the same time, and different versions can be mixed and matched in the same application. Modules may be installed by the user, and their exposed classes can then be used in applications the user creates or installs.

4. Applications

In our current desktop environment, applications are mostly monolithic. This means that an application is an entire self-contained whole, without much ability for composition with other applications. Occasionally applications may provide plugin APIs; these are ways in which developers can add extra functionality to a program. For example, most major browsers have extensions, which add extra functionality to the browser without having to download an entirely different version of it. These are nice, but the problem is that these are not at all standardized; every single application has its own special way in which you are supposed to modify it, and for non-developers it's entirely opaque how you would even begin.
While an application may allow nice interoperability of components and plugins inside it, the most interoperability between applications you'll get is possibly exporting a file. Now, you can sometimes build some sort of layer between applications if both applications provide some sort of plugin API, but this is clunky and not standardized; any skill you learn by doing this is not transferrable to building interoperability between any other two applications.
In Linlu, applications are the opposite of monolithic, they're modular. Every application is built out of objects, and each object exposes its abilities to the outside world in a uniform way. Users can modify and connect different fields together to create desired results, even in ways that the original developer could never have anticipated. Users may even take objects out of certain applications to use them in new applications.

5. Views

So far, I've been rather silent on how this all would look, as in, what the user would actually see while using this. This task would be delegated to views, which interpret objects and display what they expose to the user. Different views may display it differently; we could have a CLI-based view, or we could have a standard desktop-like graphical view, or we could have something else entirely. How these objects actually look, and how they're interacted with, is determined by the view, not by the core of Linlu itself. Views also don't necessarily have to be visual, one could design an audio-based view for blind users, for example.
That said, Linlu will come with DesktopView, which will be a somewhat standard desktop-like environment. Of course, it will be a much more composable and malleable desktop, but still a desktop. Though I am still considering other options for what views could exist—perhaps something based off of krkwd's gravitational idea could work.

5.1. Attributes

Fields and methods of objects may also have attributes; these give information to the view for how they should be displayed. For example, we may want to expose a field, but leave it hidden in a context menu, so we could add an attribute for that. Or, we may want to group multiple components together, so we could create a "Group" attribute. Attributes will give more control to the module developer on how their objects should be rendered.
Importantly though, attributes should be optional. Objects should still display fine (if maybe a little awkwardly) if attributes are ignored or not recognized.

6. Conclusion

So, that's my idea on how a new malleable computing environment would look. These ideas are still heavily in flux, so if you have any suggestions or comments, you may send them on the Linlu mailing list, or if you want it to be private, email me directly.

Footnotes

* The name is derived from the toki pona word linluwi, which means something like "network" or "connection"

Universally Unique Identifier; basically a long string of hex digits that's effectively guaranteed to be unique by randomness

References

[1] LiveSplit Contributors, retrieved February 25, 2025, "LiveSplit AutoSplitters", https://github.com/LiveSplit/LiveSplit.AutoSplitters


Groups: Projects, Linlu