Software Simplicity
I’m a big fan of Grug. Software complexity is the eternal enemy of software engineers. With GridWhale I’m fighting the Complexity Demon by aiming to keep things as simple as possible — without sacrificing power.
I started programming in the 1980s, just when simple PCs dethroned the complex mainframe giants of the world. PCs were simple: you got inputs through events (mouse-clicks, keystrokes, etc.) and generated outputs by painting to the screen (GDI, QuickDraw, etc.). And that was it.
But user requirements, like sharing data over a network, invited the Complexity Demon back in. We built client-server systems, in which multiple PC programs talked to each other. Suddenly we had to deal with RPC protocols, caching systems, and custom wire protocols. Adding a feature meant changing two programs: the client and the server.
By start of the new century, the Web simplified everything again. Writing PHP was almost as easy as writing PC code. All the processing was done on the server, and the client was just a dumb browser displaying pages. But that changed quickly: The desire for interactivity led to Ajax and client-side JavaScript. Suddenly we were writing two programs again (client and server) and we had to deal with new frameworks, distributed caching systems, and server API design. The Complexity Demon was back.
How are we going to banish it this time?
Frameworks vs. Hyperplatforms
Broadly, I think there are two major approaches to fighting the Complexity Demon: frameworks and hyperplatforms. The Node.js ecosystem uses frameworks to create abstractions that tame complexity. Frameworks are meant to be combined; an app might use React, Express, GraphQL, and Zod (plus TypeScript, of course).
The advantage of the framework approach is flexibility and power. Developers have full control down to a very low level.
In contrast, the hyperplatform approach is to create a single, unified platform that provides all the needed functionality. Phoenix LiveView is a great example: it combines frontend and backend in a single program and executes it all on the server. Hotwire and Next.js are other examples heading in the same direction.
There are obvious trade-offs in both approaches. The framework approach is powerful but introduces its own complexity. The hyperplatform approach is simple but may not have all the features you need.
If I were working at Google/Meta/Microsoft on multi-megaline repos, I’d choose the framework approach. But for smaller, well-scoped projects, I’d rather use a hyperplatform. That’s why we built GridWhale.
GridWhale
The core concept of GridWhale is simple: create a single platform that abstracts away all the complexity of modern web development. The platform is serverless, so programmers don’t have to worry about scalability. And the platform unifies frontend and backend so that programmers only have to write a single program — just like we did back in the 80s.
For example, here is a complete Hello World program:
using UI
var mainCtrl = TextControlType([
data = "Hello, world!",
align = "center middle",
fontSize = "100pt",
])
function mainCtrl.onclick () do
if mainCtrl.data == "Goodbye!" do
mainCtrl.data = "Hello, World!"
else do
mainCtrl.data = "Goodbye!"
end
end
UI.show(mainCtrl)
UI.run()
You can run it here. Notice a few things:
And the philosophy of simplicity — the idea of designing for Grug-brained developers — continues throughout GridWhale.
Composition vs. Expansion Joints
A general-purpose platform like GridWhale must expose enough functionality to support a wide variety of applications. But how should we organize the API to maximize power while minimizing complexity?
There are two main techniques: One is to create a small number of concepts that can be composed in various permutations. For example, the concepts of filter, map, and reduce can be combined in various ways to achieve different results. Another technique is to have an ever-growing catalog of tools, each suited to a specific purpose. For example, a library of statistical functions is simple to understand: you look in the documentation for the right function and call it. Over time, more and more functions are added.
I call this an “expansion joint” approach, borrowing the term from engineering: expansion joints allow structures to grow by adding discrete, independent sections. In software, this means adding new, self-contained pieces — functions, objects, etc. — instead of making developers compose existing ones in complex ways.
领英推荐
The challenge with composition is that sometimes it is hard to figure out how to compose the pieces. Documentation often focuses on individual components, not how they interact. If you have three well-documented pieces, but no examples of how they work together, you’re left guessing at the right combination.
Moreover, as the number of pieces grows, the combinatorial complexity increases geometrically — you not only have to understand each component, but also every way it might interact with the others.
Worse, it is difficult to expand the capabilities of composition. You must either introduce new components (which might interact unpredictably with existing ones) or change the behavior of existing components, which might introduce backwards compatibility problems. In contrast, adding new functionality with the expansion joint technique just requires adding new independent pieces (e.g., new functions).
Nonetheless, composition is a very powerful technique (GridWhale has filter, map, and reduce, for instance) because it enables many different results with a small number of pieces, hopefully reducing the programmer’s cognitive load.
The goal in GridWhale is to deploy each technique where it is most appropriate. For example, imagine publishing an OData endpoint in .NET. You don’t just write a function to return data — you have to assemble an Entity Data Model, create an ODataController, register OData routes, and ensure that each object interacts correctly.
I remember it took me a while to figure out how to piece it all together because each step required composing multiple objects, and missing one small detail meant the whole thing wouldn’t work.
In contrast, GridWhale just supports OData natively as a type of endpoint and handles the protocol natively. The type of endpoint is an expansion joint: we can continue to add new types as needed without requiring developers to learn a new composition model each time.
Stone Soup Integration
In the old fable of Stone Soup, a woman in a village with very little food offers to make stone soup. She starts by boiling a pot of water with a single stone. The villagers are skeptical — until she says, “It would taste better with some vegetables.” One villager adds a carrot, another adds radishes, another adds spices. In the end, everyone contributes a little. Finally, the woman takes out the stone and says, “Now it’s ready!”
Software ecosystems work the same way. If a platform provides a strong enough foundation, third-party developers will contribute valuable additions that seamlessly integrate. But if the foundation is weak, every library must reinvent its own data structures, leading to fragmentation.
GridWhale follows Stone Soup Integration by providing standard, built-in structures and systems, forming a strong, shared foundation:
Contrast this with languages that lack strong standard libraries:
By ensuring GridWhale has solid, universal abstractions, we make it easier for third-party libraries to interoperate. Developers can focus on adding valuable functionality, not writing glue code to convert between incompatible structures.
Software Simplicity
Software complexity is a relentless adversary — and often we invite it in. The very tools that we use to tame complexity — abstraction, reusability, and future-proofing, sometimes lead to complexity! It’s like the Terminator: a remorseless adversary that looks like a friend so it can infiltrate your code.
GridWhale is my attempt to push back — an effort to rediscover the elegance of simpler times while still embracing the power of modern computing. By unifying frontend and backend, eliminating unnecessary boilerplate, and providing strong batteries-included abstractions, GridWhale fights back against the Complexity Demon.
If you’re tired of wrestling with unnecessary complexity, GridWhale might be exactly what you’re looking for. Let’s make software simple again. Reach out and help shape the future.
Notes & Info
About: I’m George Moromisato, a software engineer building GridWhale, a new cloud-computing platform. Every once in a while, I’ll post an update about its development. Interested in helping out? Write to us: [email protected].
Consultant at Accenture
2 周I’m going to check this out!