Live data from Hacker News

Goodbye, Clean Code (2020)

overreacted.io

191–200 of 224 posts

Re: Goodbye, Clean Code (2020)

#191
This is a good example of what I call Similar vs Same. "Similar" code is code that happens to look very close, but is actually addressing separate use-cases. "Same" code is code that looks close, and is addressing the same use-case. Same code is safe to unify, similar code is not.

Of course, that's looks like a weak definition, because it ends up falling to, "how do you define your use-cases?" Well, that's kind of the point. The biggest thing to point out is that use-cases are not static, but change as the business changes. The second point exemplifies this:

For example, we later needed many special cases and behaviors for different handles on different shapes.

So now they're definitely separate use-cases, that just happen to look similar because they're achieving similar goals. But the methodology may and can be completely different depending on the circumstance.

So even if this was originally same code, and the unification was successful, it would have ended up split apart again anyway. And that's OK to. Sometimes things that really are the same use-case end up splitting as the business changes or learns. We as engineers need to recognize when this happens and split out the code also, instead of creating a tangled mess of one code serving two different use-cases.

EDIT: Just read some of the comments, and my thoughts expressed here are probably a subset or incomplete version of "prefer duplication over the wrong abstraction":

https://sandimetz.com/blog/2016/1/20/the-wrong-abstraction

https://news.ycombinator.com/item?id=29240647

Re: Goodbye, Clean Code (2020)

#192

"first you learn the value of abstraction, then you learn the cost of abstraction, then you're ready to engineer" - Kent Beck

Premature abstraction is the root of all evil.

I cost myself a position recently arguing about this.

I had a first round interview that went well, and was given a take home and the problem was very simple, dead simple. In turn I tried to keep the code as simple as possible, with only necessary abstractions.

The second interview was with an entirely different person who seemed displeased I didn’t bloat the solution with all sorts of enterprise patterns, dependencies and conventions. I was kinda backed into a wall and while attempting to explain my reasons I ended up in an argument with the interviewer and it was clear we did not see eye to eye. He would later challenge my ability to perform in a patronizing tone and I was sure the opportunity was dead

It wasn’t the only thing that went wrong with that interview, but I feel that disagreement was the biggest killer.

Re: Goodbye, Clean Code (2020)

#193

Earlier quoted context omitted.

I've seen a few developers see multiple "duplicated" API formats for instance (for different API's) in the same codebase and think those are "duplicated" and then entangle two completely separate API's together. This is worse IMO

There is accidental duplication to beware of. That is when different things looks the same. Then there is real duplication.. Only the later is bad and should be eliminated. Telling the differences is hard

I'd rather look at a simple arithmaticl expression and know immediately what is going on, rather than have to make up a hard to remember name for every small expression that happens to get repeated one or more times in the name of DRY. The same applies to small bits of non-arithmatical code.

Re: Goodbye, Clean Code (2020)

#194
There must be another more common term for this, but an older programmer once told me to watch out for "false parallelism" - code that is currently duplicated, but is likely to diverge in the future, and so trying to make the code part of the same abstraction would not be meaningful.

There's also the fact that with complex abstraction, you run into the problem that it can be more difficult to maintain as there's more layers of indirection.

That cost of abstraction has been mentioned elsewhere, but I want to throw out there that both of these points fall under the umbrella of a powerful concept for writing maintainable code, that you should not only think about the best way to structure your code now, but you should consider how that code will change and how that structure will facilitate or hinder that.

What I think I would have favored in this case would be to use some small, well-named utility functions that can be used to implement that math (not necessarily to replace all of it). I cannot see the code so I don't know for certain if utility functions would actually help, but I have taken this approach for geometry oriented code in the past and it worked well. In general, don't be afraid of writing small utility functions.

I don't agree with the concept of letting "clean code" go. All he's done is replace "clean code" patterns with other ones that work better for the situation. What's best is becoming familiar with new patterns like the ones I've described above, not just "clean code" patterns, weighing their benefits and downsides for the current case, and not necessarily worry about whether you're using patterns that are arbitrarily part of a paradigm that hasn't worked in other cases (however, remaining aware that you don't know every pattern).

Re: Goodbye, Clean Code (2020)

#195

Duplicated code != Messy code. The only time duplicated code is bad is when there is an actual logical requirement for the multiple instances of duplicated code to be the same. Like some actually underlying concept linking the duplicated code sections that is worth abstracting. That is not always the case. Just as often IME the situation is actually, "these two things happen to have the exact same behaviour right now…

I don't think this is necessarily true. If I have one place in my code where I sign unsubscribe tokens for emails and another place where I sign cookies for auth I don't want to implement a HMAC twice. Even if the verification paths are different so the algorithm doesn't actually need to be the same it is still better to use the same code for both so that any bugs, inefficiencies or other problems can be fixed once r…

Even if you have a number of different hashing functions, each used one, throughout the code, it would make sense to place all of the hashing functions into namespace next to each other. That way you can reuse if needed and checking for security problems is easier. (It can also make the code more readable because the details of the hashing are abstracted behind a method.)

Re: Goodbye, Clean Code (2020)

#196

Earlier quoted context omitted.

Premature abstraction is the root of all evil.

I cost myself a position recently arguing about this. I had a first round interview that went well, and was given a take home and the problem was very simple, dead simple. In turn I tried to keep the code as simple as possible, with only necessary abstractions. The second interview was with an entirely different person who seemed displeased I didn’t bloat the solution with all sorts of enterprise patterns, dependenci…

Looks to me like you dodged a bullet.

Re: Goodbye, Clean Code (2020)

#197
post #13

"Firstly, I didn’t talk to the person who wrote it. I rewrote the code and checked it in without their input. Even if it was an improvement (which I don’t believe anymore), this is a terrible way to go about it." While undeniably true, this feels completely orthogonal to the question of clean code. You could ruffle someone's feathers in the exact same way by taking code into the opposite direction. "Goodbye, Clean Co…

The thing that bothers me about conversations in opposition to "best practices" or "clean" code" is that it misses the pragmatic aspect of those concepts. WHY do we write clean code? Because the value of software is its ability to CHANGE. Otherwise we would stick with fixed circuits. Best practices and clean code don't exist in a vacuum and they are not floating abstractions that developers should throw around as if…

In the article the author said that his “cleaner” version had less duplicate code, but was harder to adapt to new usecases. His point is that clean looking code is sometimes harder to change, because while cleaning people introduce abstractions or assumptions that hinder new usecases rather than facilitating them. The right way to keep code maintainable is not always self evident, and not necessarily always clean (which I interpret as SOLID, deduplicated).

Re: Goodbye, Clean Code (2020)

#199
> My code traded the ability to change requirements for reduced duplication, and it was not a good trade. For example, we later needed many special cases and behaviors for different handles on different shapes. My abstraction would have to become several times more convoluted to afford that, whereas with the original “messy” version such changes stayed easy as cake

Yeah code duplication is fine when the commonality of code is incidental. The thing that bothers me is starting from the assumption that the requirements for each shapes are going to diverge. It looks like the wrong kind of premature optimization to me. In this case the refactoring seemed sensible, and unless they already _knew_ that this would happen soon, I think it was safe to assume that it wouldn't and that factorizing made sense. _Then_ duplicate the code in the future if it's necessary - seeing that the abstractions were not working properly.

There are tons of codebases in the wild with large portions of duplicated logic, from experience they seem the rule rather than the exception for any sizeable project. "DRY" as itself is not a rule, but I think it makes sense to be doubtful of duplication as a default stance.

Re: Goodbye, Clean Code (2020)

#200
post #13

"Firstly, I didn’t talk to the person who wrote it. I rewrote the code and checked it in without their input. Even if it was an improvement (which I don’t believe anymore), this is a terrible way to go about it." While undeniably true, this feels completely orthogonal to the question of clean code. You could ruffle someone's feathers in the exact same way by taking code into the opposite direction. "Goodbye, Clean Co…

The thing that bothers me about conversations in opposition to "best practices" or "clean" code" is that it misses the pragmatic aspect of those concepts. WHY do we write clean code? Because the value of software is its ability to CHANGE. Otherwise we would stick with fixed circuits. Best practices and clean code don't exist in a vacuum and they are not floating abstractions that developers should throw around as if…

I'm from the older generation. I don't agree with a lot of what's in clean code. Particularly the focus on micro unit tests. Nor do I like the moralising tone of the books author in general. Also flexibility comes at a cost. A codebase where everything is easy to change becomes complex in aggregate, such that nothing is easy to change.
Post reply on HN