Hacker News new | ask | show | jobs
by makapuf 3567 days ago
I agree about the dangers of over abstraction but you're implying it derives from the principles, however the lines

  The KISS principle states that most systems work best if they are kept simple rather than made complex
  Therefore, simplicity should be a key goal in design, and 
  unnecessary complexity should be avoided. YAGNI is a 
  practice encouraging to purely focus on the simplest 
  things that make your software work.
made me think that it clearly warns against overengineering.

(edit:formatting)

2 comments

Sounds good, but what concrete, objective measure of simplicity do you use? And how do you justify your choice?
I've got an extensional definition but not an intensional one. That is, I can look at two programs that do the same thing and tell you which one is simple, but I'm not sure what all goes into it at what weight.

One thing is code execution paths for later debugging. All else equal, code is simpler if everything you need to figure out what something does is in one place. Basically, minimizing the distance you need to travel in order to get related information. Keep variables closer to where you use them, etc.

There's some programming language specific stuff. A for loop that does a mapping is more complicated than calling a map on the collection. More generally, a program is simpler if it uses more specific abstractions, rather than using a very general abstraction in a highly specified way.

Likely, there's more than I'm completely forgetting but will recognize as general principles that I use.

Excellent point - I've had disagreements with people who thought their code was beautifully simple while I thought it was an over-engineered mess.

Who was right?

[NB Obviously, I was right, but it would help if there was some objective measure of complexity to justify it ;-)]

Let's take a page from the Orange Book days. Simplicity means you can:

1. Clearly map the code/functions to the specs of what it does almost line by line.

2. The code is expressed in a way simple enough for one person to understand it and verify it by hand.

3. The code is expressed in a way simple enough for a machine to verify it should someone want to try.

4. Minimal to no global effects/state happening in the local code.

These principles tend to result in code that's correct and easy to modify. I say they're a start on some objective measure of simplicity. We could empirically [dis]prove them as well with tests of various coding styles on people and tooling.

I've seen complex atrocities created by blindly following KISS and YAGNI. It just takes a non-obvious path, and a few months of code and requirements evolution.
I'll counter that comment with the following:

Blindly following anything -- especially nuanced, process-driven ideological frameworks -- is a recipe for a disaster.

KISS and YAGNI are examples of processes that require the person who is using them to actually think through the implications within the context of the problem being solved.

KISS and YAGNI did not cause the atrocities that you've seen. Those complex beasts of code existed because the team fundamentally didn't understand what they were doing.

It's like "agile" software development. Just declaring that you're following an agile methodology and scheduling stand-ups does not mean that you're going to be successful. It takes someone (and usually, many someones) who understand how to iteratively design and develop to be successful.

> It just takes a non-obvious path, and a few months of code and requirements evolution.

Can you expand on this comment? I'm interested in understanding what you mean by "non-obvious path".

> Blindly following anything -- especially nuanced, process-driven ideological frameworks -- is a recipe for a disaster.

Yep. That's the point, that's why I pointed it was blind.

Many people blindly follow and impose that kind of ideology. Most people that even mention YAGNI outside of a classroom are blind followers (for DRY things are more diverse).

By non-obvious path I mean things (requirement, underlining systems, user base size) changing in a way that was not unquestionably and blatantly obvious.

> By non-obvious path I mean things (requirement, underlining systems, user base size) changing in a way that was not unquestionably and blatantly obvious.

I can't agree with you more. Thank you for the follow-up.

If "Keep It Simple Stupid" causes one to make something complex, they have failed to keep it simple, and can't blame the principle for their failure to adhere to it.
Marcosdumay did not state that "complexity" was the problem, but "requirements evolution".

Following KISS and YAGNI means you hard code lots of assumptions. When the requirements change, it means you have to fix all those subtle hard-coded assumptions everywhere and that is usually hard.

Also, if a single concept pops up as something that's needed once every month for six months, it's way easier to have that get re-implemented six times rather than abstracted.