Live data from Hacker News

Do the simplest thing that can possibly work (2004)

twasink.net

61–70 of 95 posts

Re: Do the simplest thing that can possibly work (2004)

#61
This is effectively meaningless (and the article even recognises that) because it delegates all meaning to the definition of "works".

Even "passes all the tests" isn't a great definition. What are you testing?

For example think about build systems. "Works" could be "builds everything correctly" in which case the simplest thing is just a shell script with all the commands written out.

That's obviously terrible, so then "works" becomes "doesn't unnecessarily repeat work" and you end up with Make.

But then Make doesn't scale to large monorepos with CI so then "works" becomes "and doesn't allow undeclared dependencies" and you come up with Bazel.

So the same meaningless advice can justify wildly different solutions.

I think better advice is just "try to keep things simple where possible". It's vague because it requires experience and design skill.

Re: Do the simplest thing that can possibly work (2004)

#62
post #54
post #51

Earlier quoted context omitted.

At the risk of beating an analogy to death... this is exactly the mental model that gets us leftpad. Outsourcing of complexity is /not/ elimination of complexity. I may go my whole life without having to debug the lower-level steps in the process that put a bagel on my table, and if that's the case then treating dependencies as zero-cost makes sense -- but also, I may not be so lucky. When the supply chain collapses,…

There's nothing wrong with leftpad as a library concept. The problem was that it got hacked, not that it does something useless that everyone should write on their own. leftpad was incorporated into ECMAScript in 2017 for a reason. > Outsourcing of complexity is /not/ elimination of complexity. This is technically true but functionally false. You're literally arguing against the concept of abstraction layers, while w…

> You're literally arguing against the concept of abstraction layers, while writing text into a form built on top of hundreds of them.

Sorry, I see how what I said could have been interpreted this way. That's /definitely/ not my intent, and I'd like to clarify.

I am arguing that abstraction layers have cost, and (independently) that third-party dependencies have cost. (Abstraction layers are a great tool for isolating third-party dependencies, so they tend to go together, but they're independent things here.)

Also, lack of abstraction layers has cost, and building everything in house has cost.

These costs need to be traded. In some cases, leaning on external dependencies is the right choice. In other cases, it's not.

If complexity (opposite of simplicity) under an abstraction layer is neglected (estimated at zero), using simplicity as a guideline for making engineering decisions will lead you to the wrong decision some of the time. Similarly, if complexity under an abstraction layer is treated as just as non-simple as complexity above the abstraction layer, using simplicity as a guideline will lead you to the wrong decision some of the time.

Therefore, "the simplest thing that can possibly work" is too naïve a metric to be used for making decisions (as opposed to just for justifying decisions you already want to make). It takes a more nuanced discussion of types of simplicity, and whether complexity is being eliminated or just hidden, and if it's hidden how likely it is to stay hidden, to make this rule useful.

For the record: I buy my bagels from a store. When the roads are closed due to snow, I don't have a bagel. That's the right decision for me, unsurprisingly, for this problem.

Finally, I'll argue that there /was/ a problem with leftpad as a library concept. There is an inherent minimum complexity to a dynamically linked external dependency. The reduction in complexity of the implementation must be at least as large as this cost. One can argue about where the line lies (and it depends on the maturity of your ecosystem, etc), but I'd take the stance that leftpad is too simple to implement directly for pushing it to an external dependency to ever e the right choice.

Re: Do the simplest thing that can possibly work (2004)

#63
post #62
post #54

Earlier quoted context omitted.

There's nothing wrong with leftpad as a library concept. The problem was that it got hacked, not that it does something useless that everyone should write on their own. leftpad was incorporated into ECMAScript in 2017 for a reason. > Outsourcing of complexity is /not/ elimination of complexity. This is technically true but functionally false. You're literally arguing against the concept of abstraction layers, while w…

> You're literally arguing against the concept of abstraction layers, while writing text into a form built on top of hundreds of them. Sorry, I see how what I said could have been interpreted this way. That's /definitely/ not my intent, and I'd like to clarify. I am arguing that abstraction layers have cost, and (independently) that third-party dependencies have cost. (Abstraction layers are a great tool for isolatin…

If your point is, "abstractions don't have zero cost" point taken. But if your point is, "abstractions have meaningful cost", I'd rephrase that as, "The better an abstraction is, the closer to zero its cost becomes."

Can we agree on that?

Re: Do the simplest thing that can possibly work (2004)

#64
post #63
post #62

Earlier quoted context omitted.

> You're literally arguing against the concept of abstraction layers, while writing text into a form built on top of hundreds of them. Sorry, I see how what I said could have been interpreted this way. That's /definitely/ not my intent, and I'd like to clarify. I am arguing that abstraction layers have cost, and (independently) that third-party dependencies have cost. (Abstraction layers are a great tool for isolatin…

If your point is, "abstractions don't have zero cost" point taken. But if your point is, "abstractions have meaningful cost", I'd rephrase that as, "The better an abstraction is, the closer to zero its cost becomes." Can we agree on that?

Absolutely.

And in particular, I'd like to rephrase my original statement of:

> Outsourcing of complexity is /not/ elimination of complexity.

to

> Outsourcing of complexity /reduces/ complexity, but not all the way to zero.

Re: Do the simplest thing that can possibly work (2004)

#65

Earlier quoted context omitted.

I like to use SMBC's take[1] on the "Watchmaker Analogy" - complexity comes from, in order: (1) number of things interacting (2) complexity of interaction (3) complexity of thing So simplicity is then an inversion of that. You can "maximize simplicity" by: (1) minimizing the number of things (2) minimizing the complexity of interaction (3) minimizing the complexity of each thing This ends up reinventing many of thing…

What's interesting in Rick Hickeys video is that he talks about prioritizing minimizing what each thing does over minimizing the number of things (that you can ignore anyways). Having more things doesn't make systems more complex in itself if they can be combined differently as requirements change.

I agree and disagree! That talk is a favorite - and it's why I say "number of interacting things".

If we're weaving together three strands (basic braid), that's fine - we've got three interactions. If we take that braid and two more and weave them together, IHMO we're only adding three more interactions (now we're at 6), but if we take all nine original strands and weave them all together, we're up to, what... at least 72 "interactions" (each of the 9 has an interaction with 8 others), and that's before asking if any of the "interactions" themselves become "interacting things" (and then we get a combinatorial explosion).

If instead we take those nine, and, say, braid three together for a bit, then swap one strand out for another, braid for a bit, repeat until we've gone through all nine - each strand is interacting with, hmm... 4 others? (two, then a new one, then a second new one) So then that's "36".

It's not really a precise measurement, but I do find it useful question both when investigating a system, and when designing one: "how many things are interacting, and how can I reduce that?" (systemic complexity), followed by "how can I simplify the interactions themselves?" (abstraction leakage), followed by "how can I simplify the things?" (cleaning up well-encapsulated code).

A practical example: If I want to create a test factory for an object, how many other related objects must I create for that first one to exist in a valid state?

A practical application: I can get away with complexity in well-encapsulated code, because it's easy to come back to and fix; I won't have to modify anything "outside". But I can't get away with complexity between things, because then in order to come back and fix it, I have to deal with chunks of the entire system.

Re: Do the simplest thing that can possibly work (2004)

#66
post #17

Earlier quoted context omitted.

> As long as the abstraction layer works well for you without getting too much into the details of the implementation, it's a simple solution. But this is where the engineering intuition has to come in. "As long as you will not end up spending more time debugging the system than implementing it" is an equivalent statement -- and that requires prediction of the future. If I'm going to spend hours staring at signals on…

From my experience most of the complexity doesn't come from adding stuff (where intuition is the only thing you have, and this rule doesn't help), but when removing/refactoring stuff, or the lack of doing it. A recent known example is Elon Musk removing a lot of services in Twitter that were built over the years. Every addition probably improved the system's functionality, but the more complex a codebase gets, the ha…

Seeing as how the service is way more buggy and unreliable since then...

If I compared it to monkey with a wrench in server room, I'd be doing the monkey a disservice.

Re: Do the simplest thing that can possibly work (2004)

#67
post #64
post #63

Earlier quoted context omitted.

If your point is, "abstractions don't have zero cost" point taken. But if your point is, "abstractions have meaningful cost", I'd rephrase that as, "The better an abstraction is, the closer to zero its cost becomes." Can we agree on that?

Absolutely. And in particular, I'd like to rephrase my original statement of: > Outsourcing of complexity is /not/ elimination of complexity. to > Outsourcing of complexity /reduces/ complexity, but not all the way to zero.

Woo, agreement! And a good point, too!

Re: Do the simplest thing that can possibly work (2004)

#68
post #4

This write-up is too light to provide any real insight. In particular, how do you assess simplicity? From an example I'm currently working through on a hobby project... do I use a RS-485 transceiver with a custom line code, or do I use a 10base-T1 PHY? Ethernet, especially one pair ethernet, is undoubtedly more /complex/, with echo cancellation, a complicated line code, etc; but if I use the PHY, then /I own/ that co…

[deleted]

Re: Do the simplest thing that can possibly work (2004)

#70
post #4

This write-up is too light to provide any real insight. In particular, how do you assess simplicity? From an example I'm currently working through on a hobby project... do I use a RS-485 transceiver with a custom line code, or do I use a 10base-T1 PHY? Ethernet, especially one pair ethernet, is undoubtedly more /complex/, with echo cancellation, a complicated line code, etc; but if I use the PHY, then /I own/ that co…

I agree, the article is entirely focused on semantics. In the real world, outside of research and education, no one ever attempts to make something more complicated than it needs to be. A software project consists of thousands of different problems with solutions that must be mutually compatible through a web of compromises. You have known hard requirements, known soft requirements, known future requirements, unknown future requirements, and you're searching for the simplest possible solutions for each of them that result in something like a "minimum net complexity." The problem of "over-engineering" comes when a solution that optimized the simplicity for one concern becomes incompatible with another concern. It's inevitable in any system where requirements are subject to change over time.
Post reply on HN