Hacker News new | ask | show | jobs
by thesalsabear 990 days ago
While this is a question of what the court should presume, should we ask what does a software developer presume or doesn’t:

A software developer would presume proper working of software if it is being used widely. I would presume JavaSDK or pandas library to be working properly, inspite of the fact that pandas that 3.5K bugs file on GitHub issues. But if I am thinking about integration a less known library or using a less known software I am less confident about its working.

1 comments

Given enough eyeballs, all bugs are shallow. As such, they are complained about by thousands of people, for years.

Less ironically, one can expect widely used features of widely used software to have been tested in realistic conditions so whatever bugs there might be are at least known. But it takes an insane amount of testing to cover the phase space even of a moderately complex piece of software: look how large is the test suite of SQLite.

Apparently the only working approach to less buggy software is to compose software from small, self-contained,isolated, well-understood parts, so that you can reason about the whole more easily. This is the philosophy behind the original Unix. This is the philosophy behind functional programming. This is partly the philosophy behind actor systems (even though reasoning about async interactions is harder). I expect to see more and more of these in practice.

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.

> 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".)