Live data from Hacker News

Goodbye, Clean Code (2020)

overreacted.io

201–210 of 224 posts

Re: Goodbye, Clean Code (2020)

#201
post #114

It's weird that the author agrees with their sentiment. In my opinion, duplicating code is never the right answer. Using a different form of deduplicating would be the solution here. Just write a few functions that do the math and then call them, rather than create new abstractions that can later become monstrosities. I think they learned the wrong lesson here. Just my two cents :)

> duplicating code is never the right answer.

Say you have (a*b+c)*2.0f+d several places in your code with potentially different a b c d variables. Are you really going to make up a new name for it as a function? It's much easier to just read the expression to know what it does than to memorize a new name for every possible small occasionally duplicated expression.

Re: Goodbye, Clean Code (2020)

#202

Earlier quoted context omitted.

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

I didn't miss that, I just chose not to address it for brevity.

The problem that highlights is both a process and an experience problem. It indicates that he did not have a clear picture of the development road-map for the project, which suggests there are silos of information. There were a lot of hints about this actually. The lack of code reviews (that's where the original dev's opportunity for quality improvement should have been caught and addressed), the fact that a manager would chastise him for trying to improve code quality and the fact that he made poor design choices when trying to improve said quality really does point to a dysfunctional process.

Pointing the finger at code quality here is failing to understand the difference between the trees and the forest.

Re: Goodbye, Clean Code (2020)

#203

Earlier quoted context omitted.

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.

Don't confuse Robert Martin's book "Clean Code" with the broader concept of clean code.

"A codebase where everything is easy to change becomes complex in aggregate"

What you're describing there is a code smell that is commonly referred to as "Speculative generality" and was written about in a book by Martin Fowler called "Refactoring, improving the design of existing code." Which, incidentally is a great companion book to Robert Martin's Clean Code.

Speaking of trendy medium articles, here is one that I wrote on the concept of clean code that might help better understand what I mean when I use the term:

https://medium.com/@gspencley/what-does-clean-code-mean-anyw...

Re: Goodbye, Clean Code (2020)

#204
The problem with clean code and avoiding duplication is that you will eventually create a God class where everything inherits from. By then you will realize a lot of bugs stem from having a one size fits all God class.

Re: Goodbye, Clean Code (2020)

#205
post #75

Earlier quoted context omitted.

The abstraction is the standard case and should invite custom behaviour to be added dynamically. This extra behaviour should be added by the caller / user of the abstraction. Especially in a CRUD situation, every custom procedure will probably have a few basic steps that stay the same. All you usually need is a pre and a post hook.

See, but that's exactly what I'm saying does not work. It's tempting to think that for e.g. a CRUD situation, pre- and post-hooks are all you need. And it may be that way at the beginning, although hardly so, except for the simplest applications. But very soon , you start to run into things like (not an exhaustive list, but all are things I actually encountered while trying to do precisely what you're saying, many ye…

Some of those could perhaps be solved by an "around" hook, in addition to pre- and post-hooks, like advice[1] in Emacs. Although in OOP maybe that would be represented by a decorator class (or a subclass) that overrides the method and calls the original method?

[1] https://www.gnu.org/software/emacs/manual/html_node/elisp/Ad...

Re: Goodbye, Clean Code (2020)

#206
>> We could remove all duplication by grouping the code like this instead:

1. It seems to me that you refactored the code in the wrong dimension. I would have abstracted out a template shape object.

2. Are you not using a pull request/peer review process to accept changes into the prod branch?

3. I don't think you quite arrived at the right conclusion. While you conceed that your original conclusion was incorrect, I do think your original criticism has merit, and while your solution may provide a different set of problems, that doesn't mean that a different solution based upon the collaboration between yourself and your colleague might have been yet even better.

Re: Goodbye, Clean Code (2020)

#207

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…

Things that are coincidentially similar are much "larger" and more trivial than something that becomes easier and simpler if it is more abstract like a HMAC algorithm; for example accounting applications would care about records that need VAT and records that reference a counterpart, which are approximately 90% the same and the other 90% special cases with business logic organized according to personal taste.

Re: Goodbye, Clean Code (2020)

#208
post #75

Earlier quoted context omitted.

The abstraction is the standard case and should invite custom behaviour to be added dynamically. This extra behaviour should be added by the caller / user of the abstraction. Especially in a CRUD situation, every custom procedure will probably have a few basic steps that stay the same. All you usually need is a pre and a post hook.

See, but that's exactly what I'm saying does not work. It's tempting to think that for e.g. a CRUD situation, pre- and post-hooks are all you need. And it may be that way at the beginning, although hardly so, except for the simplest applications. But very soon , you start to run into things like (not an exhaustive list, but all are things I actually encountered while trying to do precisely what you're saying, many ye…

Exactly right, transactions being the killer/most common one.

And the proposed solutions of hooks, AOP etc all start down the road of scattering actual logic across files and methods making the code harder to reason about which seems to be the worst part of overeager abstraction.

The library Automapper from C# is another place I run into this a lot. At its core it simply maps from domain to dto properties but you soon end up needing awful unwieldy configs and magic. I'd rather have a few hundred lines of obvious mapping than ever work with automapper again.

Re: Goodbye, Clean Code (2020)

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

HN has a lot of people who seem to benefit from these types of “common sense” articles that bury the lede, judging by the fact they appear on the front page so frequently. (Putting common sense in scare quotes to acknowledge that this is new information to some, no matter how obvious to others)

I'd put it differently: HackerNews has an immune system to defend against low-quality submissions, including articles with clickbait titles, but it's imperfect. (As dang puts it, we're trying for something different than internet default here. [0])

[0] https://news.ycombinator.com/item?id=29153668

Re: Goodbye, Clean Code (2020)

#210
This hits home similar to refactoring a codebase so there is no circular dependency when trying to import a 10 line pure function rather than just copying the 10 line function somewhere else and moving on.

Also of note is the functions with an if statement at line 1 so it's basically 2 functions with 1 signiture because it started dry and then requirements changed. But hey, at least it's dry right?

Post reply on HN