Ask HN: how do you read code?
As a computer programmer, I've realized that one of the best way to improve myself is to read the code written by the masters of the art and try to emulate them. This is helped by the enormous amount of opensource code out there.
However, along the way, the very act of reading code has become a stumbling block in my journey.
I'm posting this because I want to get a perspective of how other programmers approach this problem. When faced with a huge chunk of code, how do you guys read it? do you read it line by line? do you guys put it into an IDE, look at the outline and simply jump into functions you are interested in?
Do you read through the "main" function first and then branch out to the utility functions or do the reverse where you read the utility functions and subroutines first and then figure out how they are put together?
please share with me some of the tips and tricks of code reading that you have discovered.
26 comments
[ 0.20 ms ] story [ 78.9 ms ] threadThat said, I'm not downplaying reading code; it's an important skill. But you don't have to just read the code of the masters; you can jump in and add to and fix bugs in stuff from a wealth of OSS projects and there you'll get feedback from those folks too as you get involved.
I personally get a much better understanding of a block of code if I treat it as a living thing and hack around with it seeing what breaks it and what makes it go.
But since you asked:
(1) Run the code and understand what the software DOES. If a library, write a driver program which tries out most of the functions.
(2) Look at the high-level classes (or the major organizational structures, e.g. source files) and figure out the purpose of each (e.g. CLogger -> logs errors to a file or the display)
(3a) (the fun way) Come up with a cool, simple feature you'd like to add, or something simple you'd like to change. Do it. Repeat.
-OR-
(3b) (the boring way) Find the main() function and step through the code with a debugger, stepping over function calls which are self-explanatory. Step into ones you're unsure about.
In reality, this all depends on how well the code is written. Understanding some code just isn't worth the price of admission.
I usually alternate between the two: find a good piece of code. Then try to modify it to do something different. Then look at the style of the code around the parts you touched, and see if there's a better way to do your modification. Then modify something else in the general vicinity, and repeat.
When I started at Google, I basically just hacked the Google webserver to display "Hello world" in various parts of the result page until I understood what it was doing enough to start contributing to my team.
Also, hanging out on IRC rooms is very helpful. Many people ask for code reviews before committing to the libraries and you get to see how the library evolves and what are the design decisions behind the changes.
Further when you profile you can get a call graph nicely drawn out using many utils available online. This instantly gives you a big picture.
I also second stepping in, adding feature, fixing a bug etc.
Good tools are essential. If you are programming Java, use eclipse. I hated it for the first year, but now I tolerate it. Whatever your language, use its IDE. I am also partial to UltraEdit. Write some good tools. I wrote a version of unix find for Windows among other things.
If you want code that's fun to read try the Python Cookbook. http://code.activestate.com/recipes/langs/python/ is a good resource.
I like to first familiarize myself with the overall program flow. With an IDE I can usually do this with 'called from' or similar views; if I can run the code, throwing stack traces paints a nice picture of potentially-interesting control paths, taking note of interesting details along the way.
Other than that, there's usually something I'm looking for when I dive into a piece of code. So I find that function or something that looks like the right area and start poking around the places it goes and the places it comes from, see what parameters are moving around, what side effects are taking place, etc.
I usually try to build a mental model of what I would build if I were trying to solve the same problem. It's usually not spot-on, but just doing a little thinking ahead of time helps me navigate the program more easily, predict what is going to happen, and be aware of recognizable handholds.
I try to keep an eye out open for abstractions and patterns so I can keep a sightly more terse mental model and hopefully fit more of the program in my head. If it's a really big chunk of code I'll keep pencil and paper handy and map out the program's design as a I go.
Oh yeah -- keep docs handy. Every now and then they actually help.
I've found that often it's better to make the code more legible (indenting, IDE, etc) than just trying to parsing it without.
I would say unless the code is already in great shape normally tidying it up a bit means comprehension happens much more quickly.
These usually work well together:
1. Some way to cross-reference source files. e.g. ctags.
2. Source-code level documentation. Doxygen, javadoc, whatever you have.
3. Stack traces of the running app. Set breakpoints and get stack traces. If your tools will let you do this, get periodic stack traces (e.g. once every 10th of a second) for a while. Look at what the code's doing.
I just went through two systems totaling 1.5 million lines of code.
First hint: don't even think of going through all the code. Instead, figure out what's important to you, and start putting together a demand-paged map of what you need to know.
Second hint: get a paper notebook and start writing things down soon. You'll save yourself a lot of re-researching facts that way.
For others, I skim through books/blogs/opensource code
Example, at work sometimes I need to read through other peoples code for reviews / bug fixes / enhancements. In that case I'll read the bits that matter or that I'm not sure what they're doing. Other times I might read, for example, the source to jQuery or a site or something to find out how something being done. In that case I'll try and follow where it does things by jumping between function as the compiler / interpreter would.
Where I read code is, again, something that isn't hard and fast. I'll more often than not just open it in a text editor (notepad as I'm a Windows man) but sometimes I'll load it into an IDE if it's particularly long or I'm having trouble following it in notepad.
Good question though!
http://www.swombat.com/recognising-and-learning-good
I think that the best way is not just to read, but to try to recreate the code or part of the code using the original code as a guide. It's fascinating how many decisions you'll come to that were taken in the original code too.
The good thing about doing it this way is that you'll really understand why those decisions were made. Imho you learn the most this way.
If you're reading C code, vim + cscope + grep work great.
http://mags.acm.org/communications/200810/?pg=38