Hacker News new | ask | show | jobs
by makeitdouble 991 days ago
Yes. Bugs are there, but either they're shallow, well known and worked around, or have low impact for the majority of people using them.

The epitome of that was utf-8 support for a long time: there were a huge number of bugs, but alaphabet based languages would be mostly ok, and most devs would know it was a mess and work around that as much as they can.

To me one should expect any software to be broken in numerous ways, and take the time to check what happens around the area that are critical to them.

> compose software from small, self-contained,isolated, well-understood parts, so that you can reason about the whole more easily.

That looks awfully close to the micro-service approach as well. The approach can be good, but it still gives me pause.

2 comments

> That looks awfully close to the micro-service approach as well. The approach can be good, but it still gives me pause.

Microservices aside, GP's statement seems to imply composition is like addition wrt. complexity. Unfortunately, in reality it's multiplication. Complexity multiplies with each moving part. There's hardly a better example of that to what we inherited from "original Unix" - chaining small, focused tools in pipes turns into a write-only mess after around the fourth pipe.

Software complexity isn't simply a divide-and-conquer problem, because we pay a penalty for each individual piece, and each piece of glue that connects it with other pieces. That's the whole reason we rely on abstraction and generalization so much - the ability to take a bunch of "small, self-contained, isolated, well-understood parts", put them in a box, and stick a higher-level name to it. Recursively.

Yes, composing self-contained parts is mere multiplication: if you have two sequentially connected components with m and n states, the composition has no more than m × n states (in practice much fewer).

But if you have two tightly coupled components which can arbitrarily jump into each other's code, you have (m + n)^2 states.

A four-stage Unix pipe is easy to split and thus analyze and understand, step by step, because each step is reasonably small, and has only one input and one output (presumably). Spaghetti code may be impenetrable, and only work by coincidence.

As they say, any sufficiently complex system always operates in a partly degraded state. This applies to complex software as well.

Microservices are not even about structuring your app; they are about the particular kind of deployment structure for your app. You can make a highly modular app along the lines of DDD and separation of concerns, and deploy it as a monolith for simplicity, or cut it into 2-3 large deployables. (Sadly, there are cases when a monolith remains tightly coupled, but the coupling is implemented as RPC, and the whole thing is purported to be "micropservice architecture".)