Hacker News new | past | comments | ask | show | jobs | submit login
Face It: You Can't Predict the Future (sam-koblenski.blogspot.com)
26 points by koblenski on Apr 7, 2015 | hide | past | favorite | 7 comments

I feel like I don't have time to predict the future - too busy pushing things into production...

I've worked with many future predictors though and it's absolutely horrible. Always behind schedule, always seemingly off-task, and their code is a nightmare to maintain.

Gotta admit, I'm a much greater fan of building stuff that works. If you need a gizmo later, add it later.

I predicted the future all the time. The problem was I worked in a team, so there were too many factors at play. When I was wrong, I could blame it on others who didn't follow my structures to a T.

Then I was given the chance to work on a project on my own from scratch. It was the most beautiful architecture I ever implemented. 30 deadline later, and the stress of the real world, every single new feature was so hard to add because they couldn't all be abstracted to just in case we used it more than once.

Now I had no one to blame. Today, I hard code things and don't feel bad about it because I know it doesn't matter until it matters. I can only imagine all the time I would have saved if I had this mentality in the beginning.

I think this is exactly the reason why you should make code generic enough to be re-used. We have no idea what code is going to be re-used where, so it's better to try to make sure it's easier to plug code into other unexpected places.

Besides that, what the author proposes doesn't scale very well. If you're working on a small codebase and you have a few classes that aren't as generic as they could be, it's no big deal. But things get more complex when you have a big codebase where bad design decisions can affect code in hundreds of places.

I don't build something complex from scratch, it comes from working simple systems.

I don't know where to abstract and genericize (it's a word now) code until I know where things are repeated.

I am more frustrated and confounded by my peers' attempts to abstract prematurely than I am if they had simply tried to write code that did what it needed to do instead of planning for a potential future before we have any idea what that potential future is like.

My process is

1) Write it for one case 2) When the second case comes along, consider abstracting 3) When the third case comes along, much more seriously consider abstracting 4) When the fourth case comes along, it's probably embarrassing to not have abstracted yet ... but depends on the goals of the project and the timeline and the ease of learning the abstraction for the peers.

The main reason for YAGNI is not because of wasting time upfront, although it is part of the concern.

The problem of trying to write generic code is that your generic code will inevitably become not generic enough, due to unforeseen changes of requirements. Refactoring simple code is much easier than to refactor complex abstraction layers.

Sometimes you'll find it impossible to write new abstraction layer that perfectly satisfy all implied requirements from existing abstraction layer and new requirements, and end up making compromises in areas like readability and performance, only to realize some of the implied requirements are not necessary ever.

"We have no idea what code is going to be re-used where, so it's better to try to make sure it's easier to plug code into other unexpected places."

This statement is, alas, intrinsically a contradiction. If you do not know the dimension upon which you will be reusing a function, you can not abstract it successfully.

This is not to say you can't write good code, that is solid from a DRY perspective, that will be easy to abstract later if you need to, but you're better off doing exactly that, just writing good code that you could abstract later if you need to, than trying to guess.

That said, I'm a bit of a hypocrite and believe that a senior developer actually should have limited abilities to predict how code will develop over time. It can never be perfect, but some things are just blindingly obvious and there's no point in pretending otherwise. However, I want to make the point strongly that this is something you learn after years of writing your code with DRY and YAGNI in mind... it is far better to stay simple and then learn from experience how one might be able to make certain limited predictions (and how to mitigate the extra expense if you're wrong!) than try to pretend as a junior developer that one know where things are going.

Going down another important path, I'm about to say something that sounds like a joke but is actually quite serious. The maximally generic way of writing something in Javascript looks like this:

    function plugYourStuffIn(s) { eval(s); }
You can do Anything You Want (TM)! Seriously, it's incredibly generic and powerful! It also does absolutely nothing useful. These are, inextricably, two sides of the same coin.

"Generic" intrinsically carries with it the idea of "doesn't do much". I've actually developed a near-reflexive twitch when I hear a system described as "generic" at work like it's a good thing. The act of making something generic requires you to rip out assumptions, rip out functionality to turn it into plugins, reduce the prerequisites the code requires and reduce the postconditions the code promises. Thing is, those are exactly the things we want out of our code! There's a time and place for making things "generic" but I think developers far too frequently overestimate the value it provides, because you sure can put an awful lot of work into writing code that assumes nothing, expects nothing, and provides little more than a suggested structure, but manages to spend many thousands of lines of code doing so.

Absolutely you can go too far the other way and produce brittle code that has requirements that are far too complex and makes incredibly complicated promises (that it probably fails at too)... well, I never promised programming at scale would be easy. It's a balancing act in n-dimensional space not for the faint of heart.

Indeed, when I phrase it this way, it's not hard to imagine that many of our modern problems with "bloat" and slow, overcomplicated code, ultimately stems from far, far too many layers of "generic" code and far too little code that actually does something.

Keep in mind that "You aren't going to need it" comes from evidence gathered over decades of the craft. And it focuses on premature effort. Optimize and make things generic where possible, just don't do it prematurely.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact