Hacker News new | comments | show | ask | jobs | submit login
How to improve your programming skills (antoarts.com)
232 points by antoarts on June 30, 2011 | hide | past | web | favorite | 89 comments

11. Rewrite something that desperately needs to be rewritten.

So many times I've encountered something and thought, "I can't believe that people are actually expected to use this software."

It was bad from a user perspective: difficult to use, slow, tedious to do what you actually needed to do, unable to "get there from here".

Then once I looked under the hood, it was often worse: built upon a horribly designed data structure, inflexible with constants where there should have been parameters, no apparent thought put into its use, too many violations of acceptable practice to mention, looking as if it evolved haphazardly (which it probably did).

It's easy to bitch about stuff like this, but you often have to go to the next level to do something about it. It's amazing how much rethinking you have to do and how many tools you have to build to turn horrible software into what should have "obviously" been done in the first place.

Easier said than done. And often, some of my best learning experiences.

Rewriting something is most definitely a good way to learn that a) rewrites are easy to underestimate, and often not such a good idea as they seem, and b) the previous programmer may not be such an idiot as you first thought.

Understanding the thinking behind other peoples code (yes, even crap code) is one of the hardest programming skills to acquire.

This is something that took a lot of mistakes to learn for me. Replace only the code that's definitely wrong, and resist the urge to start over. Whenever I see a project announce that they're going to rewrite the next version, I know I'll never see it.

Instead of rewriting something, you should really refactor it until it is beautiful. Unless the original author was really stupid, you are bound to go through all the same errors and dead-ends the original author went through on his first try.

I thought that edw519 was actually talking about incremental rewriting, i.e. refactoring.

"Learn a new programming language"

I would rephrase this to learn a new programming paradigm. There are fundamental differences between static typing and dynamic typing, object orientation and functional, manual memory management and garbage collection. There are also "pure" single-paradigm languages and multi-paradigm languages. If you learn the same type of language multiple times, you're really just learning new syntax and probably a couple of extra idiosyncrasies, so it's important that you pick languages with fundamental differences.

Compare going through this learning path:

Perl -> PHP -> JavaScript -> Python -> Ruby -> Node.js

To going through this:

Java -> C -> Scheme -> JavaScript -> Erlang

For example.

Counting proper languages I actually wrote something useful in, my path looks like:

C64 BASIC -> C64 raw machine code -> QBasic -> x86 raw machine code -> Turbo Pascal -> C -> Visual Basic -> Java -> O'Caml -> Delphi7 -> Python -> C++ -> Erlang -> C# -> Haskell -> F# -> JavaScript

To keep learning very different languages is also what guarantees you will be able to get a good job when your bread-and-butter language falls out of fashion. Try to imagine being a 60-year old Cobol-only programmer in the job market today. In addition to getting some experience with the actual languages, you will also get a good grip of the underlying patterns and ideas, which will make it a breeze to pick up any new language.

Another mostly overlooked skill that you gain from working in radically different languages, is to be able to work with different priorities. Java and C++ are designed for serious work. In these, you take types, error checking and exceptions seriously, you keep the code clean and robust, and you R the FM thoroughly for every single external function you call. Visual Basic, on the other hand, is designed for slapping together something that gets a small job done. Errors can be ignored, text encoding can be fucked up, functions can run into 500 lines, and that's simply something you should be comfortable with when in VB - it's copy/paste/hack/throw away all the way. C# is again very much like Java, but without the documentation attitude. Critical bits of the standard library are woefully undocumented, and you are expected to just try some code and see if it works. When in C#, just accept that and be comfortable with it.

But, most importantly when learning a new language: Adopt the mindset. Don't try for type-safe Python. Don't write slapdash C++ code. Don't try for time-critical optimized VB. Don't box/unbox everything in F# to get dynamic typing.

Java and C++ are designed for serious work. In these, you take types, error checking and exceptions seriously, you keep the code clean and robust, and you R the FM thoroughly for every single external function you call.

What type is "null" in Java? What type is the stack in C++?

Java and C++ have very little typing. You have to type a lot of types into your source code, but they don't get you anything. For every Java or C++ program, there is some set of input that results in a NullPointerException or a segmentation fault. Guess what: if you had a type system, that wouldn't happen.

Java and C++ are designed for certifications, long-lasting career, and compiling [1].

[1] http://xkcd.com/303/

Completely agree with the types part. I did not try to say that Java or C++ are strictly typed, but that the types (ie. classes) that are used in programs are taken seriously. By this I mean that if you are looked down by serious C++ developers upon if you send your references via void pointers or typecast by guessing.

> What type is "null" in Java?

> What type is the stack in C++?

    struct Stack;  // No definition

    Stack *

i always hear about how many jobs there are for cobol programmers to maintain legacy code. i've never actually met any though. maybe they all commit suicide.

My only encounter with the mythical COBOL Legacy Architect was at one job where we indadvertedly shared a desk. Since he was only in the office about 2 hours a months, others had assumed it was an empty cube and put me there. The rest of the time, he was making consulting bank in his mountain cabin. I think other than myself and the CIO, maybe 3 people knew who the guy was.

The flipside is that probably 90% of mainframe programmers were washed out of the industry in the mid-1990s. I remember seeing tons of useless resumes full of RPG and JCL and no C++/Oracle/Java/WinNT or whatever was hot back then.

I've heard about a lot as well, especially in the banking industry, yet not actually met anyone. Does anyone have any data or any numbers on how much someone can get paid doing cobol legacy maintenance? Just for educational purposes of course.

A lot of banks still have mainframes lurking somewhere on which they run (legacy?) accounting and settlement systems. Interestingly, a lot of the mainframe / COBOL programming jobs are outsourced, mainly to Indian companies. Infosys and TCS (the two huge outsourcing shops) actually train some graduates in Cobol / Mainframe programming. When I worked at ${Wall Street Bank}, we had an outsourced team in Chennai looking after a mainframe system. I had a quite a shock when I visited the Chennai office and discovered that most of the guys were straight out of college!

Ah so it isn't like theres all these American companies that are going to be paying top dollar to maintain their legacy, mission critical COBOL systems. They're outsourcing it for minimum wage.

An article [1] showed up on HN a while ago. In it the author gave a list of business which run their entire business on the mainframe. I work as a Java dev in rail transportation. The author is dead-on right - COBOL runs the world.

1. http://www.javacodegeeks.com/2011/06/hate-java-fight-wrong-b...

Yeah I remember that article, just don't see many jobs available, or any kinds of approximate numbers on what you could make for doing full time COBOL

> Java and C++ are designed for serious work. In these, you take types, error checking and exceptions seriously, you keep the code clean and robust, and you R the FM thoroughly for every single external function you call.

So how do they compare to Haskell, especially when it comes to types and code cleanliness?

For those who don't have Haskell listed in their path, I'll tell you: Haskell takes types a lot more seriously, but they're so different from what a C++ or Java programmer would think of as types that it's difficult to make a direct comparison. Ditto error checking, which, to a large extent, is baked into the type system such that it's a compilation error to not check for a lot of problems. Cleanliness is practically an obsession, to the point you'll wonder how anyone can write useful code in Haskell until a switch flips in your head and you begin to wonder how people can live with Java and C++. ;-)

Frankly, every language you learn should cause a switch to flip in your head like that.

So how do they compare to Haskell, especially when it comes to types and code cleanliness?

They let you compile code that has no possible way of working.

it's a compilation error to not check for a lot of problems

Oooh, Java has this too! Checked exceptions!

Oh, but except for the RuntimeError class of exceptions, that is, but errors never happen at runtime, right?

I went like this CPP -> Java -> Haskell -> Python -> Ruby -> Coffeescript and elisp somewhere inbetween.

I learned a lot about languages but there are many of my friends who know just PHP or Java and who are much more productive day to day than me.

My advice to someone would be to pick one language an learn it really well so you can do pretty much anything in it. Do Code Katas, make stuff all the time. When you're bored, dick around with other languages like Haskell or some of the Lisps(try to do SICP exercises).

But be productive in at least one language.

Check out some of Corey Haines's videos on practice to understand better what I mean.

The c preprocessor is a hardcore place to start programming.


I meant C++

Yeah, I said that it especially helps if the language utilises a different paradigm. It is the important thing, actually.

Learning Javascript changed my Perl for the ... more fun to write. Possibly better, too. I've started passing around coderefs as arguments to functions a lot more recently, and allowing people who use my APIs to do just that...

I've been writing code that allows you to describe a website in data and at a high level recently, and builds you up all the methods you need to interact with it. In general, when people need to provide parameters, I also let them pass in coderefs that can be executed to provide those eg:

            my $name = ref($args{'form_name'}) eq 'CODE' ?
                $args{'form_name'}->( $self, @user_options ) :
            my $form = $self->mech->form_name( $name );

Then I can highly recommend "Higher Order Perl" by M.J. Dominus (ebook for free on http://hop.perl.plover.com/book/ but the printed edition is well worth paying for too).

It essentially teaches you functional programming in Perl.

It's a great book! Here's something really cool: ultra-linguist and general bad-ass Sean Burke went through it doing all the examples in ... Javascript!


Ha! I thought I was the only one... When I first learned Perl two years ago, I wrote my programs in a very boring, imperative C-like style; in the time that passed, I exposed myself to the functional side of Python while also learning some deep Javascript; last month after having come back to Perl, I noticed that the new code I am cranking out basically looks like Lisp with some curly brackets in-between.

God, do I hope that the programmer that comes after me is as excited about the code-as-data, data-as-code paradigm as I am... Or at least can understand anything I wrote :)

I've explored similar concepts. In particular I've found it rather powerful to be able to export/import code refs with:

use YAML::Syck; $YAML::Syck::UseCode = 1;

Watch out though, when you take executable code from a user.

Not to golf your code or anything, but that's around the point where I switched to Ruby. It's almost a drop-in replacement, you can be coding in minutes with all the handy shortcuts non-PERL coders don't know they're missing.

name = args[:form_name].respond_to?(:call) ? args[:form_name].call(user_options) : args[:form_name]

Fewer sigils, no array/scalar access nonsense, real and convenient objects, etc.

Fewer sigils

As with PHP, reusing the same sigil for everything misses the point of sigils rather badly. I count five instances of two sigils in your example and each sigil character has another syntactic meaning within the same line.

If sigil means non-ascii character, there are six. If you use it to mean name-modifier (changes what the following string means) there is one, the colon. What did you mean?

And yes, colon is also the or in the ternary operator.

But there are still less than Perl, for the same length of code, and the code is simpler - .call() the thing if it.respond_to?(:call)

What did you mean?

A punctuation character considered as part of an identifier by way of a parser rule. The ? in respond_to?, in this case.

Your example isn't exactly identical because its not making use the $self object. Your example would look more like this in Perl:

my $name = ref $args{form_name} eq 'CODE' ? $args{form_name}->(@user_options) : $args{form_name};

Taking the original Perl example I would probably write it like this:

my $name = do { my $c = $args{form_name}; ref $c eq 'CODE' ? $self->$c(@user_options) : $c };

Which seems DRYer to me.

Also, randomly: I started putting bug bounties on my code on CPAN:


This made me more conscientious about what I release ;-)

I found a doc bug :-) "This module is attempts to hide the gory details". The "is" isn't English grammar.

(No, doesn't count as a bug, really)

> 10. Don’t rush to StackOverflow. Think!

Disagree with this one. My rule is, "If you get stuck for more than 10 minutes, post to StackOverflow." I'll post my question then continue trying to solve it myself. Sometimes someone will post a good answer right away, saving me lots of time. Other times I'll end up solving my problem on my own, but I'll still learn something valuable from a comment or answer somebody posts to my question. Here's a good example of what I'm talking about:


I second this opinion. My experience has been, when I post to stackoverflow, it forces me to explain the problem as clearly as possible to someone else. In doing so, I have sometimes found the solution in the code or a level of abstraction higher/lower.

Even when I post, if it's not quickly solved and gets very few hits, at least I justify the problem as being non-trivial... this is also useful in determining cost/benefit of even solving the problem (perhaps it's better to spend your time on other things).

It sounds like you value "getting things done" over "improving your skills." That's not a bad thing, but its not what the article was about.

I don't know about that. My point was that by posting to StackOverflow you can do both more efficiently. I don't see much of a point in trying to trial-and-error a problem, hunt through documentation, etc, when somebody more experienced can just tell you what to do in a few seconds. The same lesson is learned either way.

"The same lesson is learned either way."

Not at all. Learning how to find the solutions to a problem is very different from learning the solution to your specific issue. I'm not saying its always worth your time, but there is a different lesson learned when you find the solution yourself.

Yeah, that one stuck out for me. Pen and paper is a good way of solving problems in your own code. If your problem is interfacing with some external library/system/framework, which 95% of my difficult-to-fix problems seem to be, Google is often the only solution.

I'll post my question then continue trying to solve it myself

I also do that aswell. But it's a bit annoying when, within 10 minutes, my (unanswered) question is the top google result for the problem (due to high keyword relevance).

11. Learn how the entire stack works. I see way too many people coding around problems that could be solved at the server level, the network layer, etc.

Really good article, I agree with every point.

If I were to add to it I stress the importance of reading books by different authors and publishers, even if they're about the same subject. This helps you get a much wider, well-rounded view and it often improves the learning experience.

I agree, reading books of different perspectives is great.

I would also like to bring up the importance of reading "good practices" books and articles. Learning not only how to write good code for yourself, but good code for your colleagues to work with is an important skill to have. Writing maintainable code is often not trivial. I recommend reading Effective Java by Joshua Bloch.

Thank you :). I agree it is always good to see a thing from as many angles as possible. Additionally, some author might have left something out which another one did not.

-Build something that is bigger/more complex than your current skill level.

This will not only improve your skills in general, but learning from the mistakes you make is probably the best way to grow as a programmer.

By the way, I can't recommend going out and reading massive textbooks. That might be useful in a vacuum, but in reality you only have so much time. Programming should always be number one on this list; followed by: -building something completely different than your used to (either in scope, by features, or by language) -looking at code from open source projects

The main thing: always challenge yourself. When your at the inflection point of your learning curve, do something different. Expanding your boundaries will not only help you learn different technologies, but it will give you a better perspective on your actual specialties.

Some things are better found in books though. I've been reading Lisp in Small Pieces for a while now, and there's some great stuff buried in there. I don't think I would have stumbled upon it just hacking away on toy Lisps on my own.

There might be other places to find some of these things, like other compiler texts or the actual source of some Lisp compilers and runtimes, but books are often laid out in a nice pedagogical way. Reading the SBCL or Racket source would be a steep way to get to some of these ideas.

I would amend your recommendation to say, pick the massive textbooks you read carefully. Don't suffer through big, poorly written books.

thats a good point.

+1 for don't rush to StackOverflow!

You don't get better if you don't tax your brain a little, much like how you don't get stronger if you use a winch or wheelbarrow to carry a load instead of carrying it yourself.

I've been trying to get better at this myself. Although, you do feel foolish when you bang your head against something for six hours, and then you get your first (correct) answer on stack overflow five minutes after you post.

Still, if you're not feeling foolish often, you're not learning. Competence is deadly that way.

Learning to find the answer yourself is -way- more helpful than having it provided to you. Don't regret those 6 hours. It's a process.

Agreed. Plus next time you won't have to go looking for it on Stack again because it'll be ingrained, painfully, in your brain. And you'll probably learn a whole lot of other things along the way too.

StackOverflow isn't a total no-no, just don't make it priority 1.

Or, if it's important, go to stack but make a record of what it was... Then try to do the same thing without looking a weekend down the line .. sometimes things can't wait!

While people recommend reading code, like the Linux sources, I also find more code focused sites like Code Project (www.codeproject.com) very useful. These aren't blogs like Coding Horror, which are more "philosophy". These articles on Code Project typically are explaining code in detail.

I find that trying to ask my question at StackOverflow is the best way to improve. Because I have to think about how best to word my problem, and really make it clear and concise. And usually when I do that, I end up just solving the problem on my own.

Of course, I see a lot of give me teh codez there, so I can see where the author is coming from. Nevertheless, I find it to be a useful tool in helping me become a better programmer.

Good catch. This is similar to "rubber-duck debugging" (http://en.wikipedia.org/wiki/Rubber_duck_debugging).

I had the same thought. I think the author is only warning against immediately looking on Stack Overflow for existing answers. Formulating a good question of your own for SO requires a significant amount of thinking about the problem, which is what's being advocated.

I got a "Database Connection Error" (I am sure your server got hit hard with being top 5 on HN). :) The irony makes me giddy.

Yeah, I am getting thousands of visitors... :)

Really good article. Another way to improve your programming skills would be to teach someone else. I find this to be one of the best ways to solidify your understanding of something.

The article suggest reading code, which I agree is a good way to improve programming skills. But I'm a bit unsure what to do with the advice to read the linux source code. Where would you start? I find the only way to actually get to reading code, is if you have a need to understand some part of it (e.g. to fix a bug or add a feature).

So perhaps a more actionable proposal is to try to fix a bug, preferably one you care about, in some open source project.

I often go read code to figure out how somebody else does something I want to do. Usually, somebody has solved your problem better than you have.

For those of you who get a database error, I think it is the huge amount of traffic I'm getting at the moment which causes this (>1000 visits last hour). I'm using shared hosting, which might have problems with this, so in one way, you are DDOSing my site ;-). I don't know if it is safe to tell you to just wait and reload the page, but do that, BUT NOT TOO FAST!

Are you using any caching module, e.g. Hyper Cache for WP? If not, you should give it a try.

I started using one just recently. I'm not a web developer and I just installed WordPress less than a month ago. Apparently, PHP scripts are heavy to execute :S

It seems to work better now.

What I observe so far is people who learn all kind of programming languages will become very good programmers. And one who see language as a tool to solve problem and applies it smartly will become millionaire providing food for remaining good programmers.

But how does one get ideas for a project? I started learning programming using C++ about 5 months ago. I've been making good progress on learning the concepts but I just can't think of anything useful to create.

Do you do anything? Like, anything at all besides learn C++? Do you know anyone else who does things? Think about what parts of those things are suboptimal and create something to make it better.

For example, where I work, we get a lot of user-submitted content, but we can't use all of it. So we need to filter. The lady who is primarily responsible for this simply doesn't have the time to vet the massive number of images she runs across to make sure they meet some basic criteria for size and quality, so I wrote a program that mostly automates it.

Well, I'm a college student, so no I don't do much else aside from learning how to do stuff.

I'm sure you study, research, write, socialize, etc. in addition to learning C++. If not, I recommend starting. Those are all way more important than C++.

And like I said, it doesn't need to be your pain that you're relieving. Look at the people around you — even if you yourself are chained into your bed with no hope of escape, I bet you know people who do things. You can help them do those things.

For example, take a look at patio11 on this site. He's built a whole business out of a simple tool he wrote in a few hours to help a teacher make bingo cards for her students, because making bingo cards is such a soul-sucking waste of time when humans do it. (To be clear, he's put a lot more time than that into building the program and the business over the years. But it only took a few hours of coding to solve the problem.)

Ah, alright, I see what mean. So the general idea is to create something that will help make other people's lives easier?

Yeah. It's a good way to come up with a concrete idea, and it has the benefit of, y'know, actually helping people. (And helping people sometimes has the benefit of turning into paying work in the future.)

Awesome. Thanks for all the insight! I appreciate it.

I like how "Program" is all the way down at number 5

1. Learn paradigms, kinds of problems and computer science fundamentals.

2. Work on poorly-run large projects with (a) performance problems or (b) code organisation problems.

3. Work on other projects with developers that use (1) to solve the problems of (2). You'll be surprised how quickly you learn when you've seen the benefits to be had by doing things better... ;)

Reading and trying to work with the Linux kernel source is hardly a good way to get better programming skills. It's really large and hard to understand. Something like Minix, MenuetOS, or LoseThos is a much better alternative to hack on. LoseThos particularly reminds me of old school hackable boxes like the Commodore64.

All of the advice given here is good and none of the tips here are going to hurt you.

It's just another less abstract reiteration of a few truths that encompass much more than programming.

Work with different tools. Think. Talk about what you do with other people. Do all of it a lot.

i.e communicate, keep an open mind and challenge yourself

I hope that I fixed the problem now by installing a plugin (QuickCache) which caches pages and serves a normal, static HTML page when possible instead of generating a new dynamically from the PHP scripts each time. I hope.

8. is very important. Once you decide to write article, you got to have solid knowledge about the topic. You just can't write the code and see if it works :) you got to know why and how!

This is severely biased toward things that require no in-person interaction.

So I'll add two:

0. talk to other programmers 11. attend a Coding Dojo

One way to improve your programming skills: stop reading programming blogs and start programming.

Worst part of this is that you can end up sounding and feeling like you are/could be a far better programmer than you actually are; you know all of the ideals, philosophy and lingo about how to create clean, amazing code but actually turning this into real programs that solve real problems in real budget & time constraints is a very, very different thing.

Also, spend time doing focused practices. Attend a coderetreat (www.coderetreat.com)

1. Find something that you can't do. 2. Do it. 3. Repeat.

Debug other people's code.

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