Ask HN: I think My code isn't Good enough

140 points by mabid ↗ HN
I have been programming for the last 4-5 years but whenever I look at some good code written by some one else I always have this feeling that my code isnt good enough. By "good enough" I mean that my code isn't as beautiful(readable) and reusable. I always try to change the way i do things the next time but i keep getting this feeling. Do you guys ever fell like this and what you think I should do to improve on that ?

96 comments

[ 2.8 ms ] story [ 66.1 ms ] thread
It's constant, almost everyone experiences it. Best thing to do is look at some really old code you wrote and realize how far you've come. After that, write more code, read more code, write more code. Programmers all want to be better, this drive helps us become so, but it also drastically diminishes our ability to be content with our current situation. If you really want to see how far you've come. Find someone who reminds you of yourself and mentor them. It's much easier to perceive change in others than change in ourselves. Watching mentees progress reminds you of when you underwent the very same realization and helps you become more aware of liminal points in your programming journey.
> Best thing to do is look at some really old code you wrote and realize how far you've come.

When I do that, I tend to get surprised how good it looks contrary to my expectations of coming far since then.

And sometimes when I look at the code of some famous project I like, I may get surprised how bad it looks.

Maybe this is the difference between "rock star" programmers and your average perfectionists out there - the former just get the job done, while the latter spend too much time making their code look beautiful.

Here's Jeff Atwood's take on it: http://www.codinghorror.com/blog/2009/07/nobody-hates-softwa...

"I think you can tell a competent software developer from an incompetent one with a single interview question: 'What's the worst code you've seen recently?' If their answer isn't immediately and without any hesitation [the] two words 'My own.' then you should end the interview immediately."

That's a poor way to judge. I'm always looking at my code and thinking that it's not good enough, but there are definitely pieces of code that are worse that I deal with daily (I work on a code base that's > 20 years old).
It's a poor way to judge code, yeah, but the more important thing it speaks to, IMO, is the respect the developer has for the fact that other people will actually be executing the code they write.
So if I've recently seen code that is subjectively worse than the worse code I've ever written and I answer that question honestly, the interview will immediately end? That seems like a poor way to judge a developer.
You say you have been programming, but not if you are solely a programmer or building a product as well. Perhaps it would be easier to think of code as a medium to achieve a higher goal, which is functional software. I'm inclined to believe that this is more important than "code beauty" which is something highly subjective and tends to be constantly evolving with your experience.

Note I am not promoting spaghetti code. If it's not blatantly incomprehensible (i.e. you abide to some common sense) and works, you are set.

Of course this is my view after having spent non-trivial amounts of time making code beautiful, modular and reusable instead of trying to solve the problem at hand. YMMV.

//Of course this is my view after having spent non-trivial amounts of time making code beautiful, modular and reusable instead of trying to solve the problem at hand.

I can identify with that feeling. working at a startup made me realize that i have spent more time reading code than writing code. While that's not a bad thing on it's own, i had lost sight of the joy from building/improving things/product. I have been programming for 4-5 years now and pissed that i don't have a product of my own(crappy/otherwise).

You do want to improve, but just relax and do your best work. Continue to learn and read other people's code that you respect. But don't let your desire to improve and impress others stress you out. Also, consider the rule of threes on reusability: http://www.rimmkaufman.com/rkgblog/2007/10/16/rule-of-three/

It seems possible you are being exposed to mentors that are being too harsh on you. Certainly you're being too harsh on yourself. Go forth boldly and code.

Take some time to read about _why's philosophy on coding and making mistakes. I think it would do you a world of good.

Refactoring your code or yourself is not a terminal process.
I wouldn't really think too much into it. I've had the "not good enough" feeling for years, in fact, ever since I started programming!

A few years ago I started working on a game, the best ever I thought. I was so clever with everything I thought and oh I wouldn't need to refactor because I would do it right from the start!

Of course I moved on and started to work on other things for a while and when I came back I thought it was horrible, almost unusable!

This happens all the time, though at a lesser extent, for me. When I notice something new, fresh, nice or beautiful way of doing things the old way is simple not good enough. Why did you ever do it that way?

Don't bother too much - it's normal and it shows that you're always evolving and getting better. And after all, you learn by doing mistakes not by doing everything beautiful and perfect from the start.

Thinking you aren't good enough is the first step to getting better. At the risk of sounding cliched, it's the journey not the destination that's important. You never arrive at perfection anyway, so I wouldn't worry!

The best thing I can suggest is expanding your horizon as far as possible. Your profile says you're a RoR/JS programmer. Go learn some Haskell (or any other functional language; I started with Racket) and you'll find a truly different way of looking at programming, one which will change your style forever.

I think this more a life issue than a code one. In some ways if you're not looking at what you did a couple years ago and thinking "Wow, I would do that so much better now" then you aren't progressing.
Congratulations!

You have healthy appreciation and respect for work better than your own, always a good sign, and it means you should expect to keep improving simply by keeping at it. Same is true in any field.

I felt like this with my code for the first 5 years that I was coding as well. My code now isn't pristine or perfect, but I'm consistently satisfied with the quality of my final products. Here's what I did to get to the point where I'm happy with my code:

1. Debug and refactor. Early on, I'd stumble through creating a script. It was usually write three lines, see if that worked, repeat. I didn't plan ahead enough, and by the end, my code was just layers of ideas tightly held together by a file name. This aggravated me, so after I'd get my scripts working, I'd completely rewrite them from scratch, making improvements where I saw them, simplifying code wherever I could.

I've learned more debugging (generally my own) code than I have from any book or teacher.

This was a lot of time spent, but eventually I could start seeing ahead and could make those changes in real-time as I was writing them. I'm not saying that I don't go back and refactor my code now, but when I do it's usually to fix things for speed or bugs, not for code cleanliness.

2. Plan ahead. I know some people that write out the entire shell of their program -- all of the functions and names and comments of what each function will do -- before ever writing the actual logic. I never had the patience for that, but you can still plan ahead.

Take a look at what you're trying to accomplish, and find the areas where you know you don't know what you're doing. Do a bit of research on those points. See what others have done, there's a really good chance you're not the first person to do those things. If you're still not sure, ask for help. The community is almost always willing to help.

3. Clarity over cleverness, always. I always take the road that will be more easily maintainable in the long run rather than the code that will work the fastest. (But, you know, if you can hit both at once, awesome.) I like breaking things down into simple bits. All of my functions are either only accomplishing one task, or are strings to those one-task functions put together to do something complex (but is still considered one task).

4. Learn, practice, learn, practice, repeat. Don't just stick with one language, branch out and see how other languages tackle similar problems. Take a look at code that you thin is better than yours and figure out why you think that. Take a look at code that's worse than yours and figure out why you think that. Write those things down and keep a list next to your monitor. Review them each time you sit down. Put them into practice. A lot.

5. Perspective. Take a look at your own work from 2-3 years ago and look at how far you've come. You've probably covered more distance than you think. Even if you're not 100% happy with where you're at, the progress will be reassuring.

6. Finally, stop worrying about it. Think of some people that are really good at what they do: professional athletes, professional plumbers, professional anything. When they're in the clutch moments, they're not stressing about how what they're doing looks, they're in "the zone," their mind lets go and instincts take over. Programmers develop those instincts too.

You're probably much better than you think, and you're only going to get better every time you program. :)

I really like your "clarity over cleverness" rule. It seems to incorporate so many good practices: premature optimization, over-design/second system syndrome, and doing the most obvious thing.
cf. "2. Rule of Clarity" - Basics of the Unix Philosophy http://www.faqs.org/docs/artu/ch01s06.html

1. Rule of Modularity: Write simple parts connected by clean interfaces. 2. Rule of Clarity: Clarity is better than cleverness. 3. Rule of Composition: Design programs to be connected to other programs. 4. Rule of Separation: Separate policy from mechanism; separate interfaces from engines. 5. Rule of Simplicity: Design for simplicity; add complexity only where you must. 6. Rule of Parsimony: Write a big program only when it is clear by demonstration that nothing else will do. 7. Rule of Transparency: Design for visibility to make inspection and debugging easier. 8. Rule of Robustness: Robustness is the child of transparency and simplicity. 9. Rule of Representation: Fold knowledge into data so program logic can be stupid and robust. 10. Rule of Least Surprise: In interface design, always do the least surprising thing. 11. Rule of Silence: When a program has nothing surprising to say, it should say nothing. 12. Rule of Repair: When you must fail, fail noisily and as soon as possible. 13. Rule of Economy: Programmer time is expensive; conserve it in preference to machine time. 14. Rule of Generation: Avoid hand-hacking; write programs to write programs when you can. 15. Rule of Optimization: Prototype before polishing. Get it working before you optimize it. 16. Rule of Diversity: Distrust all claims for “one true way”. 17. Rule of Extensibility: Design for the future, because it will be here sooner than you think.

I've been trying practice better, as I think we all tend to mostly learn by using or reading documentation.

I started "exercising" a bit before I kick into coding. A few different exercises I made so far:

1. API Memorization: go through an API and try to build something that executes each function once. This is great with a REPL.

2. Reading code: find a sweet, highly regarded open source library, and, well, just pick up a file and read it.

3. Improving tool usage: improve typing speed, memorizing functionality of your editor, etc.

I try to do one exercise for about 30-45 minutes daily (if possible). I write down what I read or memorized in a spreadsheet. Maybe I'm anal.

I see exercises like how sports folk practice, or how musicians (I play the saxophone) do scales, etc. It just kind of rounds ya out a bit. Over time, you just get a little faster.

Really nice summary, because it applicable to almost everything, if you one paraphrases the first item as 'look around what others do, and why, learn, and then change the way you do the same things' . ^_^
what you think I should do to improve on that

Rewrite.

Write some code, make sure it works, and then look at places where it's ugly and figure out how to rewrite it so that it's better.

You won't write good code the first time, unless you're writing something that's trivial for you (too easy).

While the examples are too Java specific, the book Refactoring by Martin Fowler is a terrific introduction to the skill of improving code.

Someone downvoted this? This seems like good advice to me...
I hope for you that you'll never think your code is good enough. Keep growing.
Reusable code/efficient code is usually more complex and less readable. I find this is usually not a big issue, as I can always refactor change to the design I need later.

Just in time, not just in case.

I agree that efficient code is usually more complex and for some god forsaken reason it tends to be the least commented.

If you think to yourself, "wow! I'm really proud of that, very clever" please for the love of God leave a comment.

I find myself writing chicken scratch on a piece of paper or in a scrap file when writing a function, many of those chicken scratch comments are exactly the sort of things future developers would love to see in comments.

So...big takeaway from me (15+ years developing) is learning when to comment your code!

I recommend then you start taking tiny bits of software architecture to improve your code and your understanding of code structure. It can help with reuse, better practices, etc. For example get a copy of Ruby Design Patterns.

The things you will read about in it can open your eyes for better recognizing where you can improve your code, how ti apply _this_, how to solve _that_, and can give you ideas and new ways to look at structuring your code for better reuse.

Design patterns aren't an end on itself, but means write more modular, readable, understandable code.

If it solves the business problem your clients are paying you to help them with, your code is definitely good enough.

The people with opinions about your code are probably not paying you. So coding well is more like being polite to them. Really good code makes their lives slightly easier than average code (which is way better than no code).

But politeness goes both ways. If they see you trying to improve, they'll probably try to help you.

PS - When people want to get better at somthing, the biggest mistake they make is assuming they can get better inside their current comfort zone. So if you want to improve, get lost for a while. Try writing an OS. Or a physics engine. Or learn a Lisp. You'll be surprised how fast Experience - From - Elsewhere translates into more skill in your day job.

"Do whatever it takes to solve the business problem now and we'll worry about the other stuff later" is what produces horribly complex code bases because "later" never comes and management will never justify the time to fix things.

This presents you with a number of problems:

* It makes it harder to pivot in the future. You may end up having to rewrite a lot in order to extend the original model.

* In most cases, this means no tests.

* Maintenance costs significantly more.

* When you hire new people to work on the code base, it will take a significant amount of time for them to come up to speed and be productive in the code base.

I assumed OP was competent but not stellar, so my answer was about the difference between average and good.

You're talking about bad. I agree that no competent programmer would do the things you're describing if they could possibly help it. So we probably would have given OP the same advice if we had started with the same assumptions.

The two things that help me the most in this department are:

1) write tests first because then you can write something ugly that works and then refactor underneath passing test coverage

2) expose yourself to other peoples code. My tendency is to stare at my own stuff all day (or other people's unattractive code). A natural place to look at good code is to be quick to open up libraries you are using in a project and rummage through them as the need naturally comes up in your work

If someone is paying you to do it then by definition it is good enough in my opinion. The idea of perfect code is very abstract and impossible to ever reach. Coding is a journey and about incremental improvements I think, always try and learn something every time you sit down or you will fall behind the pack!
If you're using it for a start-up - it's much more important to deliver usable software than quality code - you can always go back and clean up the code - but if you don't get traction it's all over.

Also - consider buying code reviews from developers you respect - even a couple of hours a week can make significant difference to your quality.

I'm currently working on a startup and like the OP I was questioning how good of a programmer I am. I'm self taught and have been programming since I was in middle school computer club more than 8 years ago.

Working on this startup project has taught me that in the beginning it's all about delivering a product that works that users want. When requirements are constantly in flux and you're working hard and fast to develop a fully functional prototype there's little time for code refactoring to make it "perfect" because the longer it takes to launch the larger the possibility that someone beats you to it. As long as the code does what it's supposed to do and is not loaded with bugs and isn't terribly slow I say to just go with it.

Requirements are always changing in startup land and a good programmer adapts to make those changes and is focused on producing a workable prototype before their competition does

I know my code isn't good enough, and I've been programming for about 30 years! Not only that, my code isn't good enough, but I'm a great programmer.

I might be making some wrong assumptions, but I think the people whose code is really bad are the ones who think their code is good enough, or the ones who just code quickly without thinking. (I tend to think quite a bit and then code. In fact for the particular project I'm on right now, I'm doing a lot of thinking because I know the current architecture is not good enough. IT would be pointless to start writing code and then try to bash into shape- like building a stone bridge and then realizing you need a 57 chevy. No matter how much you take a hammer to that bridge it is never going to look like a 57 chevy.)

When I go back and look at code I did in the past, without having looked at it awhile, I see that it is really quite brilliant. I bet you'll see this in your code to. The thing is, the other person-- other's code, or your past code- is written when they have the full context of whats' being written in mind at the time they're writing it, and in the process of understanding their code you're going to see how their solution is more elegant than the naive solution you might have tried if you tried to write it just now.

Code takes thinking and refinement... and doing either will make code look better, and may be the source of your insecurity.

But, if your code really isn't "good enough", then maybe the issue is that your idea of "good enough" is too good. If its never going to be re-used, does it need to be reusable? If its not going to need constant maintenance, does it need to be beautiful? I have some code that I look at very, very rarely. Its in production, being used by customers every day, lots of customers. I know it is junk because at the time I wrote it, I was attempting to pull off a massive effort to get a product done. But the code isn't' throwing exceptions, it doesn't have bugs, and the customers are asking for new features, not fixes. So, I know its is ugly, I remember how ugly it was at the time, and every time I do have to go in I clean up bits and pieces of it. But it is working great... it is doing everything it should be.

And so, that code really shouldn't be good enough... because the time making it "good enough" is wasted time. If I wasn't the solo programmer on that project, then other programmers would likely work with me to clean it up... that's natural... but in startup land, sometimes ugly code that is solid is going to remain ugly code, because the point here is building a company.

Do you want a cathedral of very pretty code? Or do you want to build a startup?

I don't mean to denigrate your feelings... I think that your desire to improve is a good thing. I think the best thing you could do is to learn another language. (I'm just guessing that at 4-5 years you've probably really used one language a lot and 1-2 others a little bit.) Learning something radically different can improve you a lot. I'd recommend erlang (but I always recommend erlang.. it is the manly language that will make you a man (or woman))... or maybe you could use some scripting chops or whatever. Pick something out of your comfort zone, even if your'e going to be writing in your main language for a long time coming.

Knowing that other language will help you write better in your current language, and I think it will make you appreciate what you're writing in your current language better as well. I could be completely wrong here, but the best bang for the buck for me has been when I went outside my comfort zone and learned a very different language.

Finally, humans are bred, via natural selection, to have a certain amount of insecurity. We're supposed to fear that we're inadequate as it produces a wariness that helped keep us from being eaten by predators in the past.

Use it to keep you motivated to do better, but always make sure you're focusing on the right "Better". EG: IF you're in a startup, better is faster growth for the...

Wanted to do more than just up vote the above comment; Nirvana hit it on the head. The best I can do, as another 29 year developer here, is say "What he said". Take it to heart, then take it to heart again..
"The unskilled therefore suffer from illusory superiority, rating their ability as above average, much higher than it actually is, while the highly skilled underrate their own abilities, suffering from illusory inferiority."

Dunning-Kruger effect, and it is the same in most professions where 'performance' can be a subjective judgement. Teaching, definitely!

http://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect

(comment deleted)
The Dunning Kruger effect is talked about a lot on here.

More recent research casts doubt on their original study. I first heard about this on [Overcoming Bias] where they talk about a 2006 study which showed "on difficult tasks, where there is a negative bias, the worst performers are the most accurate"

[Overcoming Bias]: http://www.overcomingbias.com/2008/11/all-are-unaware.html

> When I go back and look at code I did in the past, without having looked at it awhile, I see that it is really quite brilliant.

We have the opposite experience. Whenever I see code I wrote in a past life, I see ugly code. I certainly would have written it differently if my future self wrote it. I see it as a reflection of how much I've learned since writing that old code.

I tell a lot of people: Code I wrote yesterday is great; code I wrote a year ago sucks.

Unless, of course, I do as the OP does and look at other people's code. Then even the code I'm writing now would not be good enough.

There's another way to look at this as well.

Many great novelists and authors have mentioned "rewriting" when it comes to their novels and books. "True writing is rewriting", "books are not written, they're rewritten". My experience is that comes with code too.

You write the functionality to do what you want, and then you keep to keep re-writing it to make it beautiful/readable.

"and in the process of understanding their code you're going to see how their solution is more elegant than the naive solution you might have tried if you tried to write it just now."

That I think is a great insight for me. I have been experiencing this thing without knowing.. and the rest also gives me a lot of help... may be we always keep learning and this feeling is good to keep up

I think that nearly all good developers feel their code isn't "good enough", so its nothing to worry about! This search for perfection will drive you to constantly improve and practice, which can only be a good thing!

Keep coding, and as always ask the developer community for help and advice, stackoverflow has certainly helped me a lot.

I think if you're shipping and it works, and you find you can revisit it in a few months without being completely lost, you're in pretty good shape.

I have the opposite problem where I'm generally happy with what I write, it works and is usually well-factored, but it seems to take me fucking forever to get it to that point. So count your blessings :-)

Assuming you mean programming professionally (i.e. most of every day), then five years is around the point where you become self-aware and realize your code isn't as awesome as you thought. Also, remember that if you see code published on the Internet, it was probably extremely polished, and likely written by someone who has had quite a lot of experience in a particular area.

By having to maintain my code, I learned to write simple, concise, well-documented code. Nothing teaches you about bad programming practices better than having to maintain your own code after six months or a year away from it. I've also learned that iteration is key to quality. The first time I create something, it's basically crap. By about the third time I've tackled the same sort of problem, I have some pretty good insights, and come up with vastly improved solutions. Of course, people see the output of the 3rd iteration and think I'm a brilliant, insightful programmer, not realizing that -- like everyone -- it didn't happen on my first try.

+1 for the having to maintain your own code. I remember looking back at my own code and swearing "what the *$$# was i thinking.."
This is what my boss looks for on résumés. Not loyalty so much as whether you've worked anywhere long enough to have to clean up and rearchitect after your own mistakes, rather than leave an ever-growing trail of (presumably) smoking craters.
I know what I was thinking most of the time: I want to get this thing working and out there as quickly as possible.

Deadlines are probably the root cause of most of the world's most horrific hacks.

Also, I've never once had a boss turn to me and say "you know what, forget about writing any new features for now - just refactor the code that is working just fine but looks horrible."

>Deadlines are probably the root cause of most of the world's most horrific hacks.

I definitely agree with this. I've written some absolutely terrible code in marathon sessions with an impending deadline -- in the worst case, I copy-pasted code in six or seven locations for something that could have and definitely should have been factored out into a function. I just didn't have any time to spare, I had to finish it for a demo in X hours. That whole project was a mess.

100% agreed. Deadlines made me write code that stinks really really bad
The third iteration thing is exactly what I was thinking when I read this thread. First attempt works, but it's pretty shoddy. Do it again and you get something better but still has room for improvement. By the third it's still not perfect but it's good enough to make you happy you did a good job.

My other benchmark of bad code is that you know it's bad when you have to hack it to add a new feature, and the only way to remedy that is to re-factor most, if not all, of your codebase.

I've had to do this a lot lately because I've not had chance to iterate. I know full well the code is bad. It works but it's not easily maintainable, and since it's in the context of a REST API there's a shitload of code we now have to duplicate - with minor differences - to add functionality I didn't have the foresight to plan from the start.

That of course is also the side effect of being given an entire project to do by yourself while the rest of your team does other things. The insight and assistance from colleagues or team-mates, or even friends if it comes to it, is just as valuable for writing good code. Knowledge has to come from somewhere.

"programming professionally (i.e. most of every day), then five years is around the point where you become self-aware and realize your code isn't as awesome as you thought"

yes i have programmed almost every day for the last 4-5 years. and it has been an year or so that i started feeling like this.. may be one reason is that that's exactly the time when i started looking a lot into well written open source code.. starting browsing open sources repo's and trying to understand how they have written code.. and when i understood I was like.. Aaahhhhh!!! that is awesome.. the best way to tackle this problem..

If you are programming in imperative languages, I think you can learn from Dijkstra and Gries.

In my own experience, mathematics is the only way to gain assurance.