> I just don't see how this is a "programming language" thing.

I think you're getting it just fine, because most of it isn't a programming language thing, and shouldn't be. I explain this in more detail in my paper: Can Programmers Escape the Gentle Tyranny of Call/Return [1]

We've really been able to build these kinds of architectures for some time using call/return, and particularly using OO. However, we haven't been able to directly express them in code. Andrew Black put it really well: "The program’s text is a meta-description of the program behaviour, and it is not always easy to infer the behaviour from the meta-description."

The fact that this is so indirect leads to all kinds of mayhem, with one particular kind of mayhem being that good architecture in our current systems necessarily entails indirection, which leads architecture astronauts to the conclusion that it is the indirection that is the good thing, and thus they indirect away.

> I'm still completely unsure how my logging example above would play-out.

For one, it doesn't really require a lot of linguistic support for the parts you mention. In general, the idea is to have as little in the language itself as possible. "Talk small and carry a large class library". But a little bit is needed. For streaming/pipe-and-filter support, which I think the logging would slot into, I use Polymorphic Write Streams [2]. These are just some classes implementing a pipe-and-filter architectural style using a few protocols and some triple-dispatch trickery.

They can be connected to stdout, to variables, ordered collections, to GUI text fields and surely also to logging subsystems.

The linguistic support is fairly minimal: the polymorphic "->" connection "operator", which can be used to connect filters into a pipe but is not specific to filters, and a bit of syntactic sugar that ensures defining a filter is no more effort than defining a method.

So a small script to convert input to upper case looks as follows:

#!env stsh
filter toupper |{ ^object stringValue uppercaseString. }
(stdin -> toupper -> rawstdout ) run

The 'filter' keyword introduces a filter definition, which is just shorthand for a class definition (see the C++ metaclasses proposal by Herb Sutter. This is similar but not as sophisticated).

Then we connect stdin to the filter and the filter to stdout (rawstdout, the default stdout is cooked).

I gave a number of additional examples in my UKSTUG talk:

https://vimeo.com/655812971

In a more general form, logging also enables dataflow constraints: any store can be wrapped in a logging store that logs all accesses. That logger can then be connected to a copy-stream that takes two stores and applies the operations that were logged to those stores. But you can also just connect the logging store to stdout (or a database, or a file) for debugging purposes.

There's more, but the central idea is to have as little linguistic support as possible, but of course as much as needed. It would have been nice if that could have been driven to zero, but alas that's not the case.

[1] https://www.hpi.uni-potsdam.de/hirschfeld/publications/media...

[2] https://dl.acm.org/doi/10.1145/3359619.3359748