Live data from Hacker News

The Wrong Abstraction

sandimetz.com

71–80 of 121 posts

Re: The Wrong Abstraction

#71
post #56

Isn't a bit of this governed by which programming paradigm your language uses? I get the feeling the answer and approach are much different when comparing Forth to Java.

Yes. In theory there is a programming paradigm which fixes this, called "aspect oriented programming." I haven't seen a really accessible aspect-oriented system however.

patents will do that

My point was that the way your language builds abstractions might increase or decrease the problem.

Re: The Wrong Abstraction

#72
For many decisions in programming, there are tradeoffs, and relying on general rules of thumb can be much worse than judging the specific case. And heuristics are often interpreted differently by different people.

Such is this discussion, imo. It's very possible to over-abstract. If something isn't extended, maybe it shouldn't be designed to be extendable, and if it isn't configured, maybe it shouldn't be configurable.

On the other hand, abstractions are the heart of programming, and finding a good one is what can make you much more productive and maybe even have more fun. The feeling when I've abstracted something and got more out than I put in is maybe the best feeling there is in this craft.

The difficulty is in finding the balance. I also dislike the rule of 3 as a hard general rule. There are many times when it makes sense to abstract something out of 2 uses, if there is a lot of code and clear separation and commonality involved, or you anticipate more uses later. Maybe even abstracting sub-problems out of one case makes sense, if separating the problem cleanly into two parts makes it easier to reason about. There are many times when it's a bad idea too; it depends on the specifics and it's a judgement call based on experience.

(And, I would even say, there is room for personal taste in programming about this; where the sweet spot lies may vary from person to person.)

Re: The Wrong Abstraction

#73
post #7

If only Programmer B had avoided that initial choice to preserve the broken abstraction rather than abandoning it then and there. He must have been practicing Deadline Driven Development.

> He must have been practicing Deadline Driven Development.

or The Team Has A Hammer Development

Re: The Wrong Abstraction

#74

"Programmer B feels honor-bound to retain the existing abstraction" I think it's more often likely that the next person comes along and lazily forces the most brittle, minimal change possible to make their new requirement work without thinking about the larger context. Even if that means putting a complicated conditional into the existing function, while leaving the existing function name intact. This isn't about hon…

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 making sure you understand the code. It's not some kind of separate task. It's essential for doing your job right, so you should not expect extra time allocated for it.

Just adding your small change without touching the rest of the application is usually the easiest way, though, so most people just do that instead.

The best rule I have heard is to always leave any code you touch in a better state than you found it.

Re: The Wrong Abstraction

#75

If you found yourself agreeing with article, yet have ever mocked mathematically-derived abstraction patterns like monads, it's time to reconsider. Math is, at its core, the study of abstraction. Things that have been found to be good abstractions in math probably are good abstractions in programming. Learn from history. Mathematically-derived abstractions probably are used because they are the right abstractions.

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.

Re: The Wrong Abstraction

#76

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, exponentially increasing cost.

And drying out code makes it easier to maintain, but it doesn't guarantee that the architecture isn't a mess.

The problem is perhaps that CS teaches algos, and sometimes it teaches design patterns. But there's almost no useful theory of abstraction design.

Design patterns are more or less as good as it gets, and all they do is give give you a cookbook of stock formulas to try.

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

Re: The Wrong Abstraction

#77

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…

But all we have to do is teach your half-baked "fewest, most stable dependencies" theory to the amateurs and then they'll be professionals, performing like 20 year veterans. Eye roll.

Re: The Wrong Abstraction

#78

Earlier quoted context omitted.

To be fair, working only from book knowledge and no experience is precisely what makes someone an amateur.

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.

Re: The Wrong Abstraction

#80

Earlier quoted context omitted.

Here's a very objective and powerful way to measure complexity: dependencies and volatility. Otherwise we're all saying "complex" but not being clear and likely meaning different things. For example, a lot of people believe that "not easy" = "complex" but as Rich Hickey articulates that's a counterproductive way to think of complexity. (See http://www.infoq.com/presentations/Simple-Made-Easy )

"dependencies and volatility" But what does this even mean? I'm okay with using Rich Hickey's definitions. But I don't recall that in Rich's talk.

If your system's design results in your stable components depend on the non-stable (volatile) components, your system is complex. This is because volatile components change often and these changes ripple to your stable components effectively rendering them volatile. Now the whole system becomes volatile, and the changes to it become very hard to reason about - hence complex.

Avoiding this problem has been captured, among others, by the Stable Dependencies Principle (http://c2.com/cgi/wiki?StableDependenciesPrinciple), which states that the dependencies should be in the direction of the stability. A related one is the Stable Abstractions Principle (http://c2.com/cgi/wiki?StableAbstractionsPrinciple), which states that components should be as abstract as they are stable.

Post reply on HN