At the ${NEW_JOB}, we're going through the processing of leveling up, and one of the steps of "leveling up" as a software company is watching Robert Martin (aka Uncle Bob's) Clean Code Video Series, where he presents his ideas about how code should be thought about, organized, and written. A lot of the material is okay, and there's definitely something to be said for his ideas about separation of concerns.

In the latest one, for example, he said that when reviewing the design of a system, it should shout what it's about. A payroll system should shout "Payroll!" Frequently, though, it doesn't; the organization of a project in a modern framework is often about a framework. Django apps are organized around the needs of the deployment scheme, and so are Rails and so forth. (WebObjects, the original web framework from 1996, is said to have been modeled directly on Trygve Reenskaug's 1979 paper on model-view-controller, so I wonder if it's different.)

Bob's organizational scheme is that there are Entities, which contain knowledge, Interactions which handle the events that cause entities to change, and Boundaries that present the the permissible set of events to end users. "The web stuff" should only talk to boundaries, and should be separate from the entire system; it should be possible to swap out a web-based presentation mechanism from the entire system and scale and price both separately.

This is a great idea, and one I subscribe to whole-heartedly. (I also love that it's inherent in the way Rust does CLI programs as "libraries first"; that's not in the compiler, but every example did it that way and the community has learned to do it that way.)

But there's one thing about Bob's scheme that's been bugging me. And I think I know what it is. Take a look at this:

See that blue arrow pointing at the connector between the two objects? What is that?

"Well, it's a function call. Duh."

Great. What is it? What is a function call?

You see, in Bob's world, a function call is something he never has to worry about. Compilers just do all that stuff for you. A compiler sets up space on the stack for the arguments to the composed object, as well as empty space for the returned value. All the complicated underlying stuff about allocating memory, protecting it from overwrites, reclaiming it when you're done with it, all that stuff has been elided from Bob's reasoning, and from yours and mine.

And that's fantastic. With the exception of some extreme edge cases, usually suffered by the people who write database cores and operating systems for a living, we no longer need to worry about a lot of machine details.

Until we move to The Cloud.

Look at that blue arrow again. Now imagine that, instead of a function call where all the details about the ABI (application binary interface) are hidden under a warm comforting blanket called the CLR or the JVM or dot-DLL or dot-SO or whatever, they're REST or gRPC or whatever network interface you want to imagine. They need to be protected from outside prying eyes by TLS-hardened pipes, walled off by private networks, secured with JWT or PASEO, operated inside Docker containers and managed by Kubernetes.  It needs to be "stateless," meaning that it needs to be able to die and restart and recover immediately where its previous incarnation left off.

You can still write the core of your system using Uncle Bob's UML-inflected notations about the relationships between objects. (That said, I find object orientation to sometimes be a fetish. Sometimes the elegant implementation is just a function.) But the lines between Entities, Interactions, and Boundaries are no longer handled for you by friendly compilers. You have responsibility for them.  Each object in the system, or some cluster of objects, needs to wrapped in layers and layers of security (since "the cloud" is just other people's computers you happen to be renting), performance monitoring, and recovery management.  Each object needs you to manually specify the interfaces between them, usually using something like Swagger or OpenAPI or some hand-turned REST thing for which no documentation exists.

Sometimes I think this is where cloud-oriented programming has gone terribly wrong. We dove into this highly performant and redundant system without thinking harder about how we could achieve the ease of use toward which that blue arrow once pointed.