Programming language of the future. Part 2: State management
Most programmers will agree that state management is a pain (in the head). Which is why they shy away from it at every opportunity. Languages, functional or OOP, make no difference - if state is only ever passed around to and from the database, it's all practically stateless in my book. In the industry-accepted programming model (clean model, layered model, hexagonal model) state management (database I/O) is on the outer layer - why? Oh, because you don't actually operate on entities that you store, you operate on transient entities derived from them. This abstraction is necessary, because in most modern languages state is carried by objects - and you can't store objects, only things derived from them. Be it rows in tables, or at least whole aggregates in NoSQL DBs. Actual object state can only be stored in RAM - and it doesn't survive program restarts. Language is your friend when dealing with state in RAM, but beyond it - you're on your own. ORMs and persistence frameworks, database migrations, transaction management - in the amount of knowledge needed to be competent with them, they by far exceed the core language. And aren't these a core concern of an application developer? Why isn't the language itself tackling them? Image source An issue related to state management is the management of the most important state of them all - program code. First, a program is a bunch of text files. Which don't always correlate with modules, which are the actual groupings of related functionality (unless it's the C language, where technically the entire program is one text file). Text files are stored in the filesystem - a hierarchical database (with symlinks). That database is then stored within a different database, which is a decentralised append-only ledger. Then a program is taken from that database, and through compilation, turned into a binary image. This step is often slow, so hacks such as build systems are resorted to. This image is often then packaged with dependencies (those needed after the build system) into a container. Container is packaged into a VM. Then comes deployment - code is diffed with the previous version based on lines of text that changed (and not semantics) for validation. Then programs are stopped, database migrations are applied, program images are replaced, programs are restarted. Phew. Image source But what if we just had objects, which you could live inspect and modify, which turned into text once you're inspecting them? Hot code swapping is actually quite ergonomic, as Erlang shows. As for the database - we don't need one. We just have objects, like NoSQL aggregates. This does mean that sharding, replication, quorum, all have to be taken care of by the language and the runtime - but that is a solvable problem. What we get in the end is zero friction - no compilation, no databases, no separate states of matter, in which our code can reside, semantic diffing, state migrations through hot code swapping. The program is just another object in an always-live system, never stopped or started, always available for invocation. Smalltalk implemented a system a lot like this. Image source I see no reason for state management to be as difficult as it is. I believe the pain associated with it is largely taken as a given, and not examined critically. But if a language embraces state management, and doesn't just pass it around like hot potato - old pains disappear, new opportunities open. In this blog I did default to OOP languages, because they are the only ones attempting to actively manage state - procedural ones just perform lists of operations, functional ones just call pure functions. In the next blog we will look at how exactly state is to be stored on the inside.

Most programmers will agree that state management is a pain (in the head). Which is why they shy away from it at every opportunity. Languages, functional or OOP, make no difference - if state is only ever passed around to and from the database, it's all practically stateless in my book. In the industry-accepted programming model (clean model, layered model, hexagonal model) state management (database I/O) is on the outer layer - why? Oh, because you don't actually operate on entities that you store, you operate on transient entities derived from them. This abstraction is necessary, because in most modern languages state is carried by objects - and you can't store objects, only things derived from them. Be it rows in tables, or at least whole aggregates in NoSQL DBs. Actual object state can only be stored in RAM - and it doesn't survive program restarts. Language is your friend when dealing with state in RAM, but beyond it - you're on your own. ORMs and persistence frameworks, database migrations, transaction management - in the amount of knowledge needed to be competent with them, they by far exceed the core language. And aren't these a core concern of an application developer? Why isn't the language itself tackling them?
An issue related to state management is the management of the most important state of them all - program code. First, a program is a bunch of text files. Which don't always correlate with modules, which are the actual groupings of related functionality (unless it's the C language, where technically the entire program is one text file). Text files are stored in the filesystem - a hierarchical database (with symlinks). That database is then stored within a different database, which is a decentralised append-only ledger. Then a program is taken from that database, and through compilation, turned into a binary image. This step is often slow, so hacks such as build systems are resorted to. This image is often then packaged with dependencies (those needed after the build system) into a container. Container is packaged into a VM. Then comes deployment - code is diffed with the previous version based on lines of text that changed (and not semantics) for validation. Then programs are stopped, database migrations are applied, program images are replaced, programs are restarted. Phew.
But what if we just had objects, which you could live inspect and modify, which turned into text once you're inspecting them? Hot code swapping is actually quite ergonomic, as Erlang shows. As for the database - we don't need one. We just have objects, like NoSQL aggregates. This does mean that sharding, replication, quorum, all have to be taken care of by the language and the runtime - but that is a solvable problem. What we get in the end is zero friction - no compilation, no databases, no separate states of matter, in which our code can reside, semantic diffing, state migrations through hot code swapping. The program is just another object in an always-live system, never stopped or started, always available for invocation. Smalltalk implemented a system a lot like this.
I see no reason for state management to be as difficult as it is. I believe the pain associated with it is largely taken as a given, and not examined critically. But if a language embraces state management, and doesn't just pass it around like hot potato - old pains disappear, new opportunities open.
In this blog I did default to OOP languages, because they are the only ones attempting to actively manage state - procedural ones just perform lists of operations, functional ones just call pure functions. In the next blog we will look at how exactly state is to be stored on the inside.