6 ms·
> My bigoted preconception [...] Well, I would have called you on this, but I guess I don't have to. > The abstraction is just barely enough to get the job do
by humbledrone 15y ago
> My bigoted preconception [...]
Well, I would have called you on this, but I guess I don't have to.
> The abstraction is just barely enough to get the job done [...]
Or, in other words, the perfect amount...
- deleted 15y ago[deleted]
- deleted 15y ago[deleted]
- dustingetz 15y ago> > The abstraction is just barely enough to get the job done > Or, in other words, the perfect amount... ... until your first hire
- dminor 15y agoYou shouldn't optimize a personal project for your first hire. Do the simplest thing that works, and then abstract/iterate.
- humbledrone 15y agoIn my experience as a person who has been hired before, I can say that I would absolutely prefer well-factored, but rather concrete code over towering abstractions. Sure, if something is a general feature, it should be abstract. There's nothing more frustrating, though, than wading through layers of abstractions, only to find that hidden behind them is a singular concrete implementation.
- Dove 15y agoOr, in other words, the perfect amount... Philosophically, I agree. I view premature abstraction in the same light as premature optimization. I believe both abstraction and optimization are incarnations of your understanding of the problem. You want them in important places, not necessarily everywhere, and hence you want them late enough in the engineering process that you understand which places are important. That said, within the comfort zone, there are high and low levels of abstraction. For example, in a project the size of Minecraft, I would expect CS major code to contain an ObjectFactoryFacadeCollection or two. Minecraft has nothing of the sort. It sticks almost exclusively to the Mob::HostileMob::Zombie inheritance we all grew up with. This is not bad or good[1], it's simply a reflection of the low-abstraction style of attacking problems that I associate with self-taught programmers. On the other hand, its Magic Number to Constant ratio is downright scandalous . . . ;) Though it's possible that some of that is an artifact of the compilation/decompilation process. [1] I'm lying, in this case it's a good thing.
- jiggy2011 15y agoPhilosophically, I agree. I view premature abstraction in the same light as premature optimization. It's usually easier to optimize later since optimisations are often just taking sections of code independantly and making them quicker. There is the whole 90/10 rule (or whatever it's called) that says it's better to highly optimise a few sections of bottleneck code rather than the whole thing. Trying to retrofit an abstraction to a piece of code is almost always a horrible experience frought with mess and compromise.
- sbov 15y agoPremature abstractions can have similar issues: unless you have more than 2 cases you don't necessarily know what your abstraction should look like. As the cases pile up you find yourself increasingly shoehorning implementations into abstractions that don't quite abstract correctly.
- Dove 15y agoTrying to retrofit an abstraction to a piece of code is almost always a horrible experience frought with mess and compromise. Yes, and unless the problem is trivial or your experience in the domain is such that your foresight borders on the clairvoyant, this is guaranteed to happen. No matter how much (or little) design you do up front. The key is to recognize the right time to stop and refactor, so as to keep the pain that comes with learning the problem space to a minimum.
- humbledrone 15y ago> Trying to retrofit an abstraction to a piece of code is almost always a horrible experience frought with mess and compromise. It is amazing to me that our experiences are so different: I have found the exact opposite of this statement to be true. The only way that I've ever come up with a good abstraction is by starting with something concrete (preferably two or more instances) and factoring out the commonality. Retrofitting a piece of code to an abstraction that was designed in a vacuum tends to be an exercise in frustration, due to the abstraction being shortsighted and insufficiently suited to the problem space.
- 15y ago
- hackinthebochs 15y agoI disagree. Abstraction is fundamental to programming. The more abstractions, the better. I'm not talking about design patterns here, but abstractions that hold explanatory power in your problem space. They necessarily increase code comprehension, reduce potential bugs, etc. Abstractions reduce potential bugs by reducing the 'interaction-space' of a particular entity in your code. Think about a program that has 100 variables all in one function. That is potentially 100! interactions between entities in your code. When you make a change, you have to reason about all 100! interactions to be sure you're not introducing a new bug. Abstracts greatly reduce this space. If instead you have 10 objects who each contain 10 variables, within the object you have 10! interactions to reason about. In the main function that ties each object together you now have 10! interactions to reason about. This is many many orders of magnitude easier than the original problem. The more (natural) abstractions, the better your code.
- humbledrone 15y ago> The more abstractions, the better. No. A hundred times no. If you have ever had to make sense of a complex program that was over-engineered with unnecessarily complex abstractions, you cannot possibly think that this is true. > Think about a program that has 100 variables all in one function [...] This isn't an example of code that is not abstract enough, it's an example of a basic failure to understand the principles of writing a program meant to be read by other humans. Sure, breaking that code up into understandable chunks is a form of abstraction, but it's not exactly the kind of abstraction that the grandparent was talking about. She was talking about "extremely elaborate object frameworks." I maintain that elaborate object frameworks are a bad thing, unless they are "barely enough to get the job done." Anything beyond that adds unnecessary complexity. This beautiful and poignant quote sums things up much better than I ever could: “Perfection is achieved not when there is nothing left to add, but when there is nothing left to take away” – Antoine de Saint-Exupery
- hackinthebochs 15y agoHe may have been referring to framework-level abstractions, but I was specifically referring to natural abstractions for the problem space. Blanket statements against abstractions in code is missing the point--abstractions are fundamental to programming. "Elaborate object frameworks" could mean a few different things. If you're referring to design pattern type structures, then I somewhat agree that the fewer the better. But in the general case it is not true that perfect is not being able to take anything more away. Not when humans are the ones writing and maintaining the code.
- extension 15y ago>> The abstraction is just barely enough to get the job done [...] > Or, in other words, the perfect amount... Well no, because the job doesn't end when it's "done". Minecraft is the perfect example: In the earliest versions of the game, blocks were all basically homogenous cubes of some material, so they didn't need to be oriented. Later, blocks were added that did need to be rotated in various ways, e.g. torches, stairs. But each of these blocks had their own private system for choosing, storing, and rendering their orientation. These systems were often similar, but not identical. At this point, roughly half the blocks in the game are orientable in some way and there is still no generic orientation system. Such a system would have avoided massive amounts of redundant code, prevented many bugs, made the user experience more consistent, and made various 3rd party tools much easier to develop. "You ain't gonna need it" is a cop-out. You are going to need some things. The trick is anticipating which things, and it will definitely pay off if you can guess correctly.
- deleted 15y ago[deleted]
- humbledrone 15y agoHmm, from what I can tell, Minecraft is fairly successful, despite it being a "perfect example" of not having enough abstraction. Of course, you fail to really acknowledge the risks of premature abstraction. Sure, if you could see the future, and know what patterns could be usefully factored out into abstractions, it would be good to start with those abstractions. But what happens if you incorrectly predict that an abstraction will be needed? You create a bunch of unnecessary framework code that is harder to understand, likely less efficient, and worst of all, you wasted time writing code that you didn't need. YAGNI is not a cop-out. The best way to create abstractions is from concrete examples. Write something once. Then, once you actually find yourself writing it twice, abstract it out. That guarantees that you don't waste time on things that you don't use. It also generally leads to better abstractions, because you have concrete use-cases to work from. Anyway, back to the Minecraft story, who are you to say that the game would be better if Notch followed the premature abstraction strategy? Isn't it possible, perhaps, that he would have wasted enough time implementing ivory towers of abstraction that he might have left out the features that actually made the game fun?