This made me think of the wisdom of learning between Confucius and Laozi in ancient Chinese philosophy.
Confucius treats learning as cultivation: you do not really know something just because you were instructed in it. You know it by practicing, reflecting, making mistakes, and gradually developing judgment.
Laozi gives the complementary warning: “In pursuing learning, every day something is added. In pursuing the Tao, every day something is dropped.” Mastery is not only accumulation. It is also subtraction: removing unnecessary abstraction, ceremony, cleverness, and control.
Software architecture seems to need both. You learn it in a Confucian sense, by doing real work and living with the consequences. You improve it in a Taoist sense, by noticing when the system has accumulated structure that no longer serves the people, incentives, and constraints that actually shape it.
That is why the article’s point about incentives resonates. Architecture is not just what you design on paper. It is what survives contact with the organization that produces and maintains it.
The recommendations are often very good, for example Ousterhouts A Philosophy of Software Design, but seem to be on software development in general, not actually software architecture in particular.
For that, I would recommend the classic texts, such as Software Architecture: Perspectives on an Emerging Discipline (Shaw/Garlan) and really anything you can find by Mary Shaw. Including more recent papers that explore why the field of software architecture did not go the way they foresaw, for example Myths and Mythconceptions: What Does It Mean to Be a Programming Language, Anyhow? or Revisiting Abstractions for Software Architecture and Tools to Support Them
More practically: look at why Unix pipes and filters and REST are successful, and where they fall down and why. Hexagonal architecture is also key.
And a plug for my own contribution, linking software architecture with metaobject protocols as a new foundation for programming languages and programming: Beyond Procedure Calls as Component Glue: Connectors Deserve Metaclass Status. An answer to Mary Shaw's Procedure Calls Are the Assembly Language of Software Interconnection: Connectors Deserve First-Class Status.
Answering the question: if procedure calls are the assembly language, what might a high level language look like? And also maybe that software architecture might have a brighter and more practical future ahead of itself.
In this vein, I really recommend "Architecture of Open Source Applications."[1] It's a book series where you learn architecture by example, with each chapter written by a maintainer of the project in question. This lets you learn not only what the architecture is, but what are the constraints that shaped it, usually history and changing project visions.
Not all chapters are equally good or equally interesting, that's the curse of a multi-author book, and all of them are dated, but I think the book is worth reading nonetheless.
I think this really down plays the value of mental model or strategies for organizing code. Take a compiler: often described as a sequence of transformations on an AST, taken to the extreme in the nanopass framework. That's a really useful mental model, and you can extract that model and apply it in other contexts. For example, many business applications are a sequence of transformations on JSON. So they're basically compilers. That can be good architecture in the right situation.
You don't have to call a sequence of transformations a compiler. You can say your AST is an algebraic data type, and your transformations are folds (or structural recursions; same thing). Now you have an abstract model that isn't tied to a particular application, and you can more easily find uses for it.
If you know a bit of maths you might wonder about duals. You will find codata---objects---are the dual of algebraic data. Ok, now we're programming to interfaces. That's also useful in the right context. What's the dual of a fold? An unfold! So now we have another way of looking at transformations, from the point of view of what they produce instead of what they consume. At this point we've basically reinvented reactive programming. And on and on it goes.
You can find most of this in the literature, just not usually presented in a compact and easy to understand form.
(Note, the above description is very quick sketch and I'm not expecting anyone to understand all the details from it alone.)
I’m not sure what part of the article this is attempting to critique.
But I would say that just because your preferred mental model is an abstract algebraic one where you build an abstract model that can apply to multiple situations doesn’t mean that such an architecture is best for every situation.
The article talks very clearly about the system and social constraints that it is optimizing for architecturally and ‘turning everything into a fold’ doesn’t immediately strike me as helping to meet the fast-build-feedback needs of the deep contributors and easy-and-safe-to-hack-in-modules needs of the weekend warrriors, which is what are described as the goals of the architecture.
But it also doesn’t strike me as very clearly not the case that the architecture has some of the features you’re describing.
It feels rather like you have a pet mental model which you think all architecture should subscribe to, and… I’m sorry but that seems naive.
You misinterpreted my comment. Algebraic data types and folds are an example of an architecture, that has application to many situations. They are not the only architecture, and I'm not presenting them as such.
I am trying to show 1) software architectures are useful, 2) if you abstract them you can find principles and relationships that allow you to transfer them to different domains, and transform them into different models, and 3) there is a lot of depth in software architecture and utility in learning it.
The article spends most of its time discussing social context in which architecture is developed (I agree it is important, but not everything) and in general downplays the utility of learning about software architecture (e.g. "“software design” is something best learned by doing", and later suggests there is little useful writing on software architecture).
I would like to spend my time more on gaining a mental model of the projects I work on, but I get very demotivated if I start disliking things like the programming language, certain arch. Choices or anything that gets too complex that doesn't seem like its worth my time
It's heavily dependent on the project, but I feel like working as a "fullstack dev" kind of removes the fun of programming. I'm already spending 40 hrs a week looking at the most dull project I can imagine
I think there is huge space for architecture case studies that help a non coder learn how to critique llm architecture decisions.
I’m a NP - lots of learning came in clinical rotations where you see real life situations and how they are addressed. I want something like this for software architecture.
The closest I’ve seen is the open source case study books referenced previously but these are older.
I’d like to be able to see explanations at various layers of abstraction about why certain decisions are made or not.
Software design/architecture is a strange beast. It feels that if you want to learn it, you should spend time in legacy systems and large codebases of rewrite a project 3 times to explore counterfactuals. A lot of books on the subjects are abstract and give such simple examples, they are useless.
It's really hard to provide proper guidance on software architecture, because the fundamental deployment strategies differ for each project.
For web projects, a lot of people will say Cloud is the best way to deploy, so now you're forced to build your whole project in a "Cloud friendly" architecture.
When I was learning and being formally educated I regularly only had like 50 bucks to my name, I couldn't even afford the cheapest VPS I could find. So for me learning the architectural ideas of using AWS services where you have to setup credit card information to even register was not feasible. After all I already had a computer, why not learn how to deploy from there? Especially after reading about horror stories of people racking up huge cloud bills due to some slip up.
So AWS was out of the window. Next I got myself a book about Microservices which was popular at the time, but quickly learned that they are about organizational structure rather than software architecture, so I never had a reason to try that architecture.
I still have no idea how to chose the right architecture or make the "correct" decisions on it. I do whatever works and for some reason it still pays my bills. Currently I just use Laravel monoliths for everything and I am pretty sure this is good enough for most web services out there.
I know the original post wasnt about webapps, it's just where I find myself having the most issues.
nevertheless, I often deceive myself into thinking that I am inventing a new design. In reality, I am usually just being shaped by the IoC model imposed by the framework and by the pressure of business requirements.
Only the scale changes. Similar problems tend to leave similar structures behind.
Sometimes it feels as if earlier generations of programmers have already solved so many of the important problems that all that remains for me is rediscovery.
But I do not want mere rediscovery. I want to create a new kind of problem. Still, in front of the solidity of established engineering, my small mind sometimes feels as if there is no place left for me.
Confucius treats learning as cultivation: you do not really know something just because you were instructed in it. You know it by practicing, reflecting, making mistakes, and gradually developing judgment.
Laozi gives the complementary warning: “In pursuing learning, every day something is added. In pursuing the Tao, every day something is dropped.” Mastery is not only accumulation. It is also subtraction: removing unnecessary abstraction, ceremony, cleverness, and control.
Software architecture seems to need both. You learn it in a Confucian sense, by doing real work and living with the consequences. You improve it in a Taoist sense, by noticing when the system has accumulated structure that no longer serves the people, incentives, and constraints that actually shape it.
That is why the article’s point about incentives resonates. Architecture is not just what you design on paper. It is what survives contact with the organization that produces and maintains it.
- That's why X works. - Not X but Y.
And some moron will be in the replies, saying "LLM comment". I hate this world. But probably yeah. llm comment.
For that, I would recommend the classic texts, such as Software Architecture: Perspectives on an Emerging Discipline (Shaw/Garlan) and really anything you can find by Mary Shaw. Including more recent papers that explore why the field of software architecture did not go the way they foresaw, for example Myths and Mythconceptions: What Does It Mean to Be a Programming Language, Anyhow? or Revisiting Abstractions for Software Architecture and Tools to Support Them
More practically: look at why Unix pipes and filters and REST are successful, and where they fall down and why. Hexagonal architecture is also key.
And a plug for my own contribution, linking software architecture with metaobject protocols as a new foundation for programming languages and programming: Beyond Procedure Calls as Component Glue: Connectors Deserve Metaclass Status. An answer to Mary Shaw's Procedure Calls Are the Assembly Language of Software Interconnection: Connectors Deserve First-Class Status.
Answering the question: if procedure calls are the assembly language, what might a high level language look like? And also maybe that software architecture might have a brighter and more practical future ahead of itself.
Not all chapters are equally good or equally interesting, that's the curse of a multi-author book, and all of them are dated, but I think the book is worth reading nonetheless.
[1] http://aosabook.org/
You don't have to call a sequence of transformations a compiler. You can say your AST is an algebraic data type, and your transformations are folds (or structural recursions; same thing). Now you have an abstract model that isn't tied to a particular application, and you can more easily find uses for it.
If you know a bit of maths you might wonder about duals. You will find codata---objects---are the dual of algebraic data. Ok, now we're programming to interfaces. That's also useful in the right context. What's the dual of a fold? An unfold! So now we have another way of looking at transformations, from the point of view of what they produce instead of what they consume. At this point we've basically reinvented reactive programming. And on and on it goes.
You can find most of this in the literature, just not usually presented in a compact and easy to understand form.
(Note, the above description is very quick sketch and I'm not expecting anyone to understand all the details from it alone.)
Shameless self promotion: the book I'm writing is about all these concepts. You can find it here: https://functionalprogrammingstrategies.com/
But I would say that just because your preferred mental model is an abstract algebraic one where you build an abstract model that can apply to multiple situations doesn’t mean that such an architecture is best for every situation.
The article talks very clearly about the system and social constraints that it is optimizing for architecturally and ‘turning everything into a fold’ doesn’t immediately strike me as helping to meet the fast-build-feedback needs of the deep contributors and easy-and-safe-to-hack-in-modules needs of the weekend warrriors, which is what are described as the goals of the architecture.
But it also doesn’t strike me as very clearly not the case that the architecture has some of the features you’re describing.
It feels rather like you have a pet mental model which you think all architecture should subscribe to, and… I’m sorry but that seems naive.
I am trying to show 1) software architectures are useful, 2) if you abstract them you can find principles and relationships that allow you to transfer them to different domains, and transform them into different models, and 3) there is a lot of depth in software architecture and utility in learning it.
The article spends most of its time discussing social context in which architecture is developed (I agree it is important, but not everything) and in general downplays the utility of learning about software architecture (e.g. "“software design” is something best learned by doing", and later suggests there is little useful writing on software architecture).
It's heavily dependent on the project, but I feel like working as a "fullstack dev" kind of removes the fun of programming. I'm already spending 40 hrs a week looking at the most dull project I can imagine
I’m a NP - lots of learning came in clinical rotations where you see real life situations and how they are addressed. I want something like this for software architecture.
The closest I’ve seen is the open source case study books referenced previously but these are older.
I’d like to be able to see explanations at various layers of abstraction about why certain decisions are made or not.
When I was learning and being formally educated I regularly only had like 50 bucks to my name, I couldn't even afford the cheapest VPS I could find. So for me learning the architectural ideas of using AWS services where you have to setup credit card information to even register was not feasible. After all I already had a computer, why not learn how to deploy from there? Especially after reading about horror stories of people racking up huge cloud bills due to some slip up. So AWS was out of the window. Next I got myself a book about Microservices which was popular at the time, but quickly learned that they are about organizational structure rather than software architecture, so I never had a reason to try that architecture.
I still have no idea how to chose the right architecture or make the "correct" decisions on it. I do whatever works and for some reason it still pays my bills. Currently I just use Laravel monoliths for everything and I am pretty sure this is good enough for most web services out there.
I know the original post wasnt about webapps, it's just where I find myself having the most issues.
And when you try to prevent that IoC from leaking into the domain too much, the design often starts to look like hexagonal architecture.
Programming often feels like inventing a new form, but in the end we tend to converge on the shapes that previous programmers already discovered.
nevertheless, I often deceive myself into thinking that I am inventing a new design. In reality, I am usually just being shaped by the IoC model imposed by the framework and by the pressure of business requirements.
Only the scale changes. Similar problems tend to leave similar structures behind.
Sometimes it feels as if earlier generations of programmers have already solved so many of the important problems that all that remains for me is rediscovery.
But I do not want mere rediscovery. I want to create a new kind of problem. Still, in front of the solidity of established engineering, my small mind sometimes feels as if there is no place left for me.