I remember working with Jade, a Windows-based software environment heavily inspired by Smalltalk, about 20 years ago. All its objects were persistent (or could be selected as persistent or runtime-only) making it both a programming language and a database. It stored all its objects in a database called the “schema”, which I assume is much like a Smalltalk image, and used Smalltalk-like browsers/inspectors to do all the code editing. Though you could export and import the class method code (not the object instance data, sadly) into text files for safekeeping.
Exporting your code was necessary because the schema would reliably crash at random times, making your database garbage and your complete system unusable. At that point all you could do was create a fresh schema and import your exported code, and of course you’d lost all your “persistent” data.
That experience gave me a bit of a sour view of the whole Smalltalk experience. It’s not okay for me for a runtime to crash ever (unless the physical machine it’s on has a hardware fault), but here it was, a supposedly enterprise-ready production system, crashing every day.
Jade’s still around today ( https://www.jadeplatform.com ) and the UI feels very much like it did back then. Not sure if they’ve fixed the crashing problem.
What mechanisms can we find that protect users from change in their code?
I’ve always thought that an object-based system ought to start with a fundamental mechanism of an object representing a changeset or a snapshot. Ie, a base environment plus a set of changes (additions, deletions, or mutations); if you query it for something not in the changeset, it passes the query to its attached environment object. You could make it read-only or read-write, because read-only objects have massive superpowers that it’s worth using. Then, you could just stack up an arbitrary number of those objects to be “semi-permeable membranes” at whatever level of scale you want. You’d use them to represent imports/exports, backups, diffs, commits, transactions, views, applications, volumes/drives, containers, virtual machines, software defined networks, private clouds… etc. You could even create one of them to represent “an arbitrary chunk of the entire Internet, or at least the slice of it that your application cares about”, and bundle it with your app so it can work when the Internet servers it was built for eventually go offline.
The resistance-to-failure part is that at every level, every snapshot could just be reverted if any of the changes “inside” it break (reverting being especially easily if you have read-only snapshots). You could have everything from small transactions (interactive undo/redo) to sandboxes to entire coordinated versioned releases of large networks represented by the same snapshot concept.
Sadly, nobody ever defined this abstraction or built it, so we just keep reinventing it over and over, badly and lossily. But I’d love to someday see it happen.
If we wanted to have a go at making this today, we could probably start with JSON as a base. Not that JSON is a great data model, but it’s everywhere now and everyone knows it. Dictionaries with string or integer keys.
Imagine if you could scale a single JSON data structure to the size of the Internet? By allocating a server to each key. Then scale it down so that your local LAN is one subkey, your local computer is a subkey of that, your current login session is a subkey of your computer, every running app is a subkey, every variable binding in a function call is a subkey… like Plan 9, but as JSON rather than a filesystem. Preferably not automatically routing every access call though untrustworthy Silicon Valley hyperscalers. I feel something like that would be really useful. It would be an actual “cyberspace”, with data locality, snapshotting and change management built in as core required concepts.