Live data from Hacker News

Goodbye, Clean Code

overreacted.io

441–450 of 599 posts

Re: Goodbye, Clean Code

#441
post #424
post #420

Earlier quoted context omitted.

Are you sure merging code for different datafeeds would be better though? In such cases, what is identical and what is not, should be references to eachother in comments. But you don't know beforehand which approach would be better, unless you know the datafeeds will stay the same as now. The sad story here is that if you know the datafeeds will stay pretty static, there's little to gain making an advanced abstractio…

If you have a 95% match on something nontrivial (and it likely won't diverge significantly), I'd go for merging even with 2 cases. At least merge most of the common parts. Reading a couple of ifs, and some not-quite duplicate procedures seems much better than having a complete 2-set in cross-refenenced files.

With a 95% match, you really only have one use case, with some minor variation.

Re: Goodbye, Clean Code

#443

I’ve usually heard this phenomenon called “incidental duplication,” and it’s something I find myself teaching junior engineers about quite often. There are a lot of situations where 3-5 lines of many methods follow basically the same pattern, and it can be aggravating to look at. “Don’t repeat yourself!” Right? So you try to extract that boilerplate into a method, and it’s fine until the very next change. Then you ne…

Loved the "incidental duplication" term. I will def start using it from now on.

But to add to this, I want to say that the moment you find your self writing a "helper" function, that's the moment when you must realize that you didn't understand the problem quite good.

As a rule of thumb and what I am always trying to pass to my peers at work etc, is to always try and think in terms of your domain and the models in it.

- What models does this helper function is acting upon or on behalf?

- Does it make more sense to create a model and put that function in it?

- Should that function be in a specific model or more that one?

Re: Goodbye, Clean Code

#444

Earlier quoted context omitted.

I thought all of this until I got used to Go's error handling. There's a couple aspects to this: 1. After a while, the "if err != nil {" becomes a single statement in your mind, and you only notice it if it's different (like trapping things that should error with "if err == nil {"). In other words, it only feels verbose if you're not used to it. After a while, the regular rhythm of "statement, error check, statement,…

"It isn't magic!" mantra is often heard in Go apologetics, but every time I see it, it occurs to me that Go's definition of "magic" is somewhat akin to a 15th century peasant seeing a lightbulb. Stuff like exceptions or error types isn't magic - they have been around for a long time, they're well understood, and they have significant advantages.

Except exceptions are rarely understood and used correctly by most programmers. They can simplify program structure, but at the expense of proper errorhandling and error mitigation strategies.

Golang is still in the sort of niche that builds databases, queues, container-orchestration, etc., but can be built for other things given enough care for spending the extra effort simplifying the solutions.

Re: Goodbye, Clean Code

#445
Code should be easy to debug and troubleshoot six months later by someone else.

Think about realistic bugs. Somebody had a minor typo or conceptual error and got a sign wrong in the math. That happens.

You're going to get a bug report a year later about "resizing the top left of a text box has the wrong gap space".

In the original code, you can look at the TextBlock area and resizeTopLeft to instantly narrow down the location of the bug, and compare it to its neighbors resizeTopRight and in like 30 seconds, duh, you subtracted the gap from the X in resizeTopLeft just like resizeTopRight and obviously the symmetrical version would be adding the gap for left because you subtracted from X coordinate for right and they're symmetric, build test, now it moves two pixels the correct direction, commit, close bug, done in like five (labor cost expensive) minutes, depending on build and test system, LOL. You should also look into why the unit test system missed this, but perhaps your fully automated unit testing does not check pixel perfect UI operations, so these things will just happen.

Is there anything for Jenkins implementing pixel perfect UI testing, and how would one spec all the millions of possible actions and combinations of actions? A startup opportunity for someone?

In the new code, its going to be possibly the rendering of everything is messed up and you have to decode and store and analyze the entire design of the entire system in your head simultaneously and run numerous simulation examples in your mind until you realize technically the gap spacing should be -1 times the absolute value of X coord or whatever abstract and elaborate formula. Or maybe you added the absolute value of a negative number which would only affect one left/right side's gap or similar complicated bug. Its going to be a VERY expensive bug, like an hour, maybe a day if its really mysterious and the debugger just doesn't "get" obfuscated code.

Also in the original code you can trivially compose one discrete example at a time and experiment with what changes when implementing the next example. Its going to be written and tested very quickly. You don't have to worry about symmetry related bugs to make TopLeft work at the same time as TopRight and BottomLeft and all that.

In the new code, its very impressive to other programmers but your boss is going to notice you have to pack the entire system into your head in a perfect and 100% correct manner before anything works at all, which seems inefficient.

The most nifty looking abstraction possible isn't necessarily optimized to be anything other than the most nifty abstraction. Its statistically unlikely to hyperoptimize for X where important values of Y like debug-ability or speed of writing are the actual real world goals.

Basically, always simplicate and add lightness, and in some situations, "clean code" is not simple and light. Sometimes clean is obfuscated by some perspectives.

Re: Goodbye, Clean Code

#446
Clean code is not about eliminating repeated code. Clean code is about readability. It's a not a rule. It's a programming philosophy.

People set rules but we should always see the reasoning behind the rules instead of just following them blindly.

Personally every time I refactor some piece of code, I think "Does this make code easier to read and understand? Will this save me and my colleagues time in the future?".

Re: Goodbye, Clean Code

#447

I’ve usually heard this phenomenon called “incidental duplication,” and it’s something I find myself teaching junior engineers about quite often. There are a lot of situations where 3-5 lines of many methods follow basically the same pattern, and it can be aggravating to look at. “Don’t repeat yourself!” Right? So you try to extract that boilerplate into a method, and it’s fine until the very next change. Then you ne…

Another thing you can do when a function becomes overencumbered is to split the remaining similar logic into smaller functions which are composed into specialized functions. This has benefit in that when analyzing modules, you can spot differences in procedure at a glance instead of needing to dig through 100 lines of somewhat similar imperative code.

Right. There are two kinds of such refactoring / DRY-ing up the code:

1) Specialized helper sub-functions/classes to make the codeblocks DRY.

2) Functions/classes to make separate features DRY.

Problem arises when the design or understanding of the code doesn't reflect the realities of changes over time, forcing you to restart/revert, or making spaghetti code with optionals and whatnot to accomodate the rising complexity.

The agile approach would be to make the code that is easiest to change either way, and prevent being locked in to only one approach.

Re: Goodbye, Clean Code

#448

Earlier quoted context omitted.

Sandi Metz wrote a blog post about this: https://www.sandimetz.com/blog/2016/1/20/the-wrong-abstracti... > The moral of this story? Don't get trapped by the sunk cost fallacy. If you find yourself passing parameters and adding conditional paths through shared code, the abstraction is incorrect. It may have been right to begin with, but that day has passed. Once an abstraction is proved wrong the best strategy is to r…

Sandi Metz's blog (and book) are an absolute gold mine. I'm a junior developer ( If there was a required reading list for professional developers, I would put her work on with zero hesitation, I feel it to be that important.

You call devs Junior until they have over 5 years experience? Wow, that’s harsh

Re: Goodbye, Clean Code

#449
As usual with code principles/guidelines, it's about knowing when to apply them, and how much to apply them. In the particular scenario discussed in the article, I think the better option would have been something in between.

I think most devs go through learning phases with code guidelines, code patterns and the like, when they first hear about them, actively trying to crowbar them into every line of code, even if it results in more complex code - because they treat these things as laws, rather than guidelines.

IME, good devs eventually grow out of this, and from experience are much better able to apply guidelines and patterns when it's "suitable" to do so.

This problem is sometimes exacerbated by management, who like to focus on metrics. For example, a project I recently worked on used SAST (SonarCloud), with all sorts of arbitrary restrictions enabled: less than 3% duplicated code, minimum 90% test coverage etc. Predictably, it helped make the code more complex than it needed to be, and led to mock-heavy unit tests that didn't seem to actually test anything - they existed only to satisfy SonarCloud (and ergo, management).

Re: Goodbye, Clean Code

#450
I constantly see devs applying DRY in ways that conflict with the “single responsibility principle”. It’s like they just stop at DRY because it’s a simple concept to understand and relatively easy to defend . I’ve seen people essentially labeled as heretics for suggesting that DRY (and any other SOLID principle) should not be blindly applied to every piece of code.
Post reply on HN