Live data from Hacker News

Do the simplest thing that can possibly work (2004)

twasink.net

21–30 of 95 posts

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

#21

If this is applied to programming, then just be aware that "doing the simplest thing that can possibly work" integrated over time typically won't result in anything good. For any given task, the simplest thing that can possibly work will often have other effects that are hard to quantify on the spot (like increased tech debt). If you're working on things that are intended to be short lived, then just do whatever is n…

Maybe. But it's often a lot easier to get from having something simple and working to something more complex and also working than it is to spend the whole time with nothing working until the complex part is completed.

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

#23
I feel like this advice works really well in some places and really poorly in others.

I think those using safe languages and broad frameworks have a much greater ability to execute on "keep it simple" than those who use something like C and build 100% of their code in-house.

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

#24
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…

> the equivalent question is internal implementation vs external dependencies.

Liabilities. Take the Windows EULA, its a contract that states MS is not liable for anything, standard software contracts state the same, so if boils down to being able to prove negligence, which can be sued for.

For example, do you trust the suppliers? IF they are in a different country, what's the chance of legal recourse if negligence can be proved, knowing about political interference if the entity is valuable enough?

So yes I agree, how do you assess simplicity, and as Billy Gates would say... it 's complicated!

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

#25
post #10
post #8

Earlier quoted context omitted.

Obligatory Simple Made Easy link: https://www.youtube.com/watch?v=SxdOUGdseq4 Simple is a matter of intuition, and that can't be transmitted to others easily, or with a single class or book. At one particular job we got punished by the business for calling things 'easy' when what we mean is that we understand the problem and all of the steps are (mostly) known. Our boss coached the hell out of us to say 'straightforw…

Agreed. But I also think that "simple to implement," "simple to debug," and "simple to test" are different metrics -- and that one has to choose which one to optimize for. This is independent from assessment of "simple" varying with intuition -- "simple" alone isn't a coherent concept.

And, to add a bit more nuance, simplicity can also depend on the stage a project is at... It may be really simple to implement core functionality to demonstrate an idea, but developing on that code can add a lot of complexity later. For example, adding security late in a project is almost always much more difficult than adding a small amount up front. Even the simple to implement metric can be a difficult judgement call.

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

#26
post #10
post #8

Earlier quoted context omitted.

Obligatory Simple Made Easy link: https://www.youtube.com/watch?v=SxdOUGdseq4 Simple is a matter of intuition, and that can't be transmitted to others easily, or with a single class or book. At one particular job we got punished by the business for calling things 'easy' when what we mean is that we understand the problem and all of the steps are (mostly) known. Our boss coached the hell out of us to say 'straightforw…

Agreed. But I also think that "simple to implement," "simple to debug," and "simple to test" are different metrics -- and that one has to choose which one to optimize for. This is independent from assessment of "simple" varying with intuition -- "simple" alone isn't a coherent concept.

The rules of Chess aren't that hard. The rules of Go are even easier. You can literally spend your whole life unpacking the implications of the rules of either of those games.

Ultimately both are 'too simple', resulting in a combinatorial explosion of states, and at least a quadratic expansion of consequences.

We often write software to deal with consequences of something else. It's possible and not that uncommon for the new consequences to be every bit or more onerous than the originals. I call this role a 'sin eater' because you're just transferring suffering from one individual to another and it sounds cooler and more HR appropriate than 'whipping boy'.

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

#27

The sentiment is nice but ceases to be useful when people have trouble distinguishing what could possibly work from what appears to work for a bit and then breaks down horribly. And it's not really about the fallibility of people. Often in engineering you can be designing in a space with a lot of unknowns, that simply can't be resolved without building out a bit to explore the space more. In such case some level of f…

Yeah sometimes you have to do the complicated thing, the saying "you can't build a ladder to the moon" comes to mind

I do think that many people make the wrong tradeoff in terms of complexity to features ratio though.

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

#28
post #17

Earlier quoted context omitted.

Actually Rick Hickey's talk ( https://www.youtube.com/watch?v=LKtk3HCgTa8 ) is amazing because he talks about your case by going back to the original meaining of words: ,,Complex comes from the Latin complecti, which means “to entwine around, to embrace'' Simplicity requires layering, so in your examples the main requirement for simplicity is about how intertwined your hobby project is with the transciever code or et…

> 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…

Then comes the engineering maxim, that you can only componentize things that have standard features and quality.

Software engineering gets the shorter straw, because there's a strong force stopping standardization and pushing components into a single implementation. It then becomes a judgement of trust, not of requirements satisfaction.

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

#29
post #16
post #10

Earlier quoted context omitted.

Agreed. But I also think that "simple to implement," "simple to debug," and "simple to test" are different metrics -- and that one has to choose which one to optimize for. This is independent from assessment of "simple" varying with intuition -- "simple" alone isn't a coherent concept.

That's part of the section in Programming Perl that sticks in my memory. From my copy... > Efficiency > ... > Note that optimizing for time may sometimes cost you in space or programmer efficiency (indicated by conflicting hints below). Them’s the breaks. If program- ming was easy, they wouldn’t need something as complicated as a human being to do it, now would they? > ... > Programmer Efficiency > The half-perfect p…

I've been dealing with a batch processing task that's written in NodeJS (partly because it was the tool at hand, partly because it does offline a process that can be done online so it's reusing code), and global interpreter locks are definitely introducing some new nuances to my already fairly broad knowledge of performance and concurrency. Broad not in the sense that I am a machine whisperer, but that I include human factors into this and that explodes the surface area of the problem, but also explains quite a lot of failure modes.

In threaded code it's not uncommon to analyze a piece of data and fire off background tasks the moment you encounter them. But if your workload is a DAG instead of a tree, you don't know if the task you fired is needed once, twice, or for every single node. So now you introduce a cache (and if you're a special idiot, you call it Dynamic Programming which it is fucking not) and deal with all of the complexities of that fun problem.

But it turns out in a GIL environment, you're making a lot less forward progress on the overall problem than you think you are because now you're context switching back and forth between two, three, five tasks with separate code and data hotspots, on the same CPU rather than running each on separate cores. It's like the worst implementation of coroutines.

If instead you scan the data and accumulate all the work to be done, and then run those tasks, and then scan the new data and accumulate the next bit of work to be done, you don't lose that much CPU or wall clock time in single threaded async code. What you get in the bargain though is a decomposition of the overall problem that makes it easy to spot improvements such as deduping tasks, dealing with backpressure, adding cache that's more orthogonal, and perhaps most importantly of all, debugging this giant pile of code.

So I've been going around making code faster by making it slower, removing most of the 'clever' and sprinkling a little crypto-cleverness (when the clever thing elicits an 'of course' response) / wisdom on top.

Post reply on HN