Live data from Hacker News

The Wrong Abstraction

sandimetz.com

91–100 of 121 posts

Re: The Wrong Abstraction

#91

Earlier quoted context omitted.

Or maybe programmer B is trying to maintain a monolith of pasta for which there is no documentation, the original programmer has long since left the company, no one is entirely sure what the business rules of the program are actually supposed to be, there are no tests, and you don't have time to actually read and understand all 100k lines of code. Management just needs this one little feature tweaked, so you dive in…

You can always chose to change the surrounding code whenever you are adding something to an existing mess, to make a bit less mess. I have heard excuses about not being given time to do it from the management many times before, but the fact is that you are the one who deals with the code, you need to make the decision. If you are not comfortable doing some change, you are the one who needs to be writing the tests or…

I don't think this is a realistic attitude. I've gotten my fingers burned more than once by trying to take this approach.

The problem with web applications is that they are not self-contained. You don't necessarily know who or what is calling what or how for some legacy applications.

I can agree with the concept of improving code as you see it, but changing the abstraction--the topic of conversation here--cannot be done willy-nilly for any non-trivial app. You have to dig up all the people are, or were, or will be counting on that abstraction, and that's a challenging thing to do sometimes.

And then you have to provide a business reason for you to allocate the time necessary to go read those 100k lines of code and understand them or write tests for them. And you tell your boss this is a mess and needs serious work, and he says, "Dude, this isn't rocket science, and we're going to burn this whole thing down in a few years anyway, and all I need you to do is add this one button in this edge case and don't break our standalone desktop app that isn't going to get updated to understand this functionality."

You're idealism is admirable, and I don't disagree with it. But the reality of the world is that if you work for a company whose primary product is not software (hell, even sometimes when you do!) the priorities are about the business functionality, not about the state of the code or the right abstraction.

I just think it's a little disingenuous for people to have these conversations in a vacuum and attribute anything from malice to incompetence to a person who takes a different approach.

Re: The Wrong Abstraction

#92

I can tell an amateur programmer from a professional by looking at their order of priorities when they grow a code base. Amateur programmers tend to put code de-duplication at the top of their priority list and will burn the whole house down to that often-trivial end. This writer is pointing out that there are other concerns that far, far trump duplicated code -- and she's right. However she's not elaborating enough…

Additionally, what I also see that tends to separate out experienced vs inexperienced programmers is attempting to deduplicate things because they appear similar. By this, I mean that these two things just happen to do similar things or have similar fields, but the operation or structure that they are attempting to represent is fundamentally different.

When they eventually diverge, because they were different operations or structures, so they won't evolve the same... This is where you end up with functions that take 10 different option parameters, all of which activate a different code path. Or structures with completely different fields set depending on where it came from. And guess what? Now you're back to basically one code path or structure per use case, and an extra dependency that didn't exist before and is a nightmare to maintain without breaking one of those existing use cases.

Re: The Wrong Abstraction

#93
post #48

I can tell an amateur programmer from a professional by looking at their order of priorities when they grow a code base. Amateur programmers tend to put code de-duplication at the top of their priority list and will burn the whole house down to that often-trivial end. This writer is pointing out that there are other concerns that far, far trump duplicated code -- and she's right. However she's not elaborating enough…

> The real offense when we factor duplicated code is the new dependency that is added to the system. A slight tangent on that note, but I think many of the problems with current web development result from the same root cause: adding yet another dependency to solve an almost trivial problem. Sometimes going to the extreme of for the sake of saving few keystrokes. Need one function to find an item in a collection? Ref…

I think javascript is intrinsically going to be one of the worst examples of that. Stemming back to the days when javascript programmers learned that using a library like (then jQuery) lodash is the _only_ way to correctly get your code to work in all cases. That culture then became ingrained, and in my opinion helped lead to the state most JS packages are in these days.

In my experience, this is one of the greatest things about the new prevalence of tools like babel; it pushes that abstraction layer down below in-code dependancies. There's still a dependency to manage, but it's not a library import or similar.

Re: The Wrong Abstraction

#94
post #58

I can tell an amateur programmer from a professional by looking at their order of priorities when they grow a code base. Amateur programmers tend to put code de-duplication at the top of their priority list and will burn the whole house down to that often-trivial end. This writer is pointing out that there are other concerns that far, far trump duplicated code -- and she's right. However she's not elaborating enough…

Dependencies (coupling) is an important concern to address, but it's only 1 of 4 criteria that I consider and it's not the most important one. I try to optimize my code around reducing state, coupling, complexity and code, in that order. I'm willing to add increased coupling if it makes my code more stateless. I'm willing to make it more complex if it reduces coupling. And I'm willing to duplicate code if it makes th…

> I'm willing to add increased coupling if it makes my code more stateless.

I like statelessness as a top priority. However I'm not sure how statelessness ever comes into tension w/ coupling. Aren't they mostly orthogonal concerns?

> I'm willing to make it more complex if it reduces coupling.

Complexity = f(Coupling), in my definition. So an increase in coupling results in an increase of complexity. Sounds like you have a different definition of complexity -- I'd love to hear it.

Re: The Wrong Abstraction

#95

Earlier quoted context omitted.

I don't think math is the study of abstraction. It seems to me it's proving truths about formal systems. Abstraction has the same purpose in math as it does in programming, a tool to more effectively communicate ideas.

Not sure I agree. Usually, mathematics is developed backwards - you have a concrete question that you want to answer, and you reason that it can be answered so long as such and such as true. The formal system is developed post-hoc to give yourself a language to reason in, but you're really trying to take the result you already "knew" to be true, and find the least restrictive system description to which it still appl…

Thanks for the response.

> People have been grinding on what the definition of a set should be for a century, trying to build the best possible abstraction, and they have all of the same problems coders have. You assume to much, it's not very general. Don't assume enough, there's nothing interesting to say that's unilaterally true.

This is a great point.

Re: The Wrong Abstraction

#96

It's funny how often I've made this argument with even fairly experienced programmers and they seem to have a visceral reaction to the code being "less dry" than it could possibly be. Similarly, once a codebase uses several very wrong abstractions, it becomes significantly more confusing to work on, exponentially increasing cost. The temptation to use a mature library as a dependency is very strong since time is init…

It's all a bit no-true-Scotsman though. abstraction != dry bad abstraction != anti-dry Abstraction is primarily about separation of concerns, not about avoiding repetition. Drying out code that's repeated all over isn't the same as creating a formal abstraction for some element of the overall logic. Which is why >once a codebase uses several very wrong abstractions, it becomes significantly more confusing to work on,…

Precisely. Very well put.

If anything, some developers use design patterns as a grab bag when solving a problem... a better approach is to model the solution and then be ready to "back in" to a design pattern upon noticing strong similarity or observing that the design pattern is a bit more abstract way of doing the same thing.

Because of the tendency to pick a pattern first and design for the domain later, many instances of design pattern use in the wild are subtly (or not so subtly) incorrect.

> Beyond that, there's no useful way to reason about abstractions, test them for domain fit, or rate them for elegance and efficiency.

Very true indeed. Looking at a design through the lens of coupling and testability and modularity is a good start and can reveal many problems, but I think the real gotcha has to do with naming: Once we name a concept/abstraction we are likely to reason within that abstraction, and we rarely consider whether we are stretching it too far, or if it is even that thing anymore.

Re: The Wrong Abstraction

#97
post #63

Earlier quoted context omitted.

Off the top of my head, there are two reasons people seem to de-duplicate code. One is because two or more things happen to share similar code. Another reason is because two or more things must share similar code. It seems like you are speaking of the first reason. There is no dependency, and the programmer is creating one. IMHO you should have at least 3 instances before creating an abstraction to reduce your code.…

I think that principle I've heard before called "1, 2, 3, abstract"; as in, wait until you see it at least three times before considering extraction. I'd also add - wait until the code is 'stable', i.e no longer under active architectural development, connected only to other stable parts (or with stable/authoritative interfaces) and having then existed in such a state for a continued period of varied usage. then refa…

Agree. Frequency matters. If it is used everywhere, no reason not to abstract.

Re: The Wrong Abstraction

#98

Earlier quoted context omitted.

Novice, not amateur. Amateurs aren't paid, professionals are. Novices are inexperienced, journeyman and masters are more skilled and experienced. A novice can have a ton of knowledge (from books), but be too inexperienced to apply it. A novice can be a professional, this is what internships and entry-level jobs are supposed to be for. Paired with mentorship and structured work assignments (structured in the sense of…

Professional means you teach (notice the word root in "profess" as in "professor"). It really means you know enough that you can teach others how to do it right, not about get paid for it per se.

Do professional football players teach playing football? Some, probably, but not all. We don't call those who don't teach amateurs. They're getting paid. The amateurs are the high school and (arguably) college players, along with rec club and pick-up game players.

You're noticing a common root, but not the meaning of the word in the modern day.

Decimate means to destroy 1 in 10 of something (like an opposing army). But today we use the word to mean destruction of a large percentage.

I suppose an argument can be made that modern use of amateur is more akin to what used to be novice. However, I'd have a hard time accepting that except when it's used as a slur. We talk about amateurs in many fields, but don't intend to dismiss them as unskilled or inexperienced, we're classifying them as non-professionals. In a forum like this, filled with amateur programmers, it seems, to me, that it's wrong to misuse the term in this manner when a large portion of the readers here are amateur programmers but of moderate to high skill level.

Re: The Wrong Abstraction

#99

I can tell an amateur programmer from a professional by looking at their order of priorities when they grow a code base. Amateur programmers tend to put code de-duplication at the top of their priority list and will burn the whole house down to that often-trivial end. This writer is pointing out that there are other concerns that far, far trump duplicated code -- and she's right. However she's not elaborating enough…

Additionally, what I also see that tends to separate out experienced vs inexperienced programmers is attempting to deduplicate things because they appear similar. By this, I mean that these two things just happen to do similar things or have similar fields, but the operation or structure that they are attempting to represent is fundamentally different. When they eventually diverge, because they were different operati…

> This is where you end up with functions that take 10 different option parameters, all of which activate a different code path.

Or you could abstract the commonalities out into a higher-order function.

Re: The Wrong Abstraction

#100
One thing I've put a lot of thought into recently is what parts of a program should typically be abstracted, because when you come across them they might be your best bets for big wins.

Top of the list: constants should probably all go in special structures with the goal of guaranteeing consistency and making them easy to understand at a glance. Everyone might know that charge code "X" means a check payment, but what happens when a new developer looks at that code with "X"s everywhere? It's more verbose to use constants.chargeCodes.CHECK_PAYMENT but nobody will misunderstand what you mean, and your IDE will be able to verify that your codes are valid. That's worth an awful lot of extra characters.

Bonus win: when your legacy backend finally gets upgraded, you have the option to change to a new code for check payments, easy as pie.

Post reply on HN