We don’t teach students how to read code. Actually we don’t event teach them that they should read code for the most part. The closest we get is sample code in textbooks, demos, and for AP CS teachers the case study. Even there I think we could do more. One of the great learning experiences of my early learning career involved reading some code. My professor handed me a deck of cards (yes this was some time ago.) He explained that they had purchased this set of functions to help enable graphics programming but somewhere along the line the documentation had been lost making this code unusable. There were almost no comments in the code either. My task was to figure out the code and create some documentation so that other people could use these routines. With all the enthusiasm and confidence of youth I jumped in with gusto. It took a while but I accomplished the task. In the process I learned a lot about both figuring out code and using graphics functions. Both served me well over the years. I still think about that now and again wondering if that sort of thing could be globally useful in education. Or is it just mean?
I still enjoy reading and figuring out other people’s code. In some ways that, especially when debugging is involved, is more fun for me than writing code from scratch. I’ve never really organized my thoughts about reading code before but I’ve been thinking about it lately and thought I’d put it down so you all could tell me how wrong I am. Or at least tell me what else you do when studying code that is new to you.
I like to read code on paper. Yes old fashioned and kills trees but it lets you look at more code at one time than you can see on a screen. I know that there is some discussion that any code that doesn’t fit on one screen should be broken up into smaller pieces and to some extent I agree. On the other hand some things don’t fit on one screen and more then that often you can benefit from more context than one method on one screen. Also I like to draw lines and write notes and that is easier on paper.
In he early days code was often “ugly” with no indentation or helpful formatting. In fact we used to have special software called “prettyprint” programs that would reformat code by adding indentation, consistent use of white space and “punctuation.” I especially remember using software like this on PASCAL programs when I was teaching high school. The need for this sort of thing is less today than it used to be. IDEs like Visual Studio for example will automatically format code and even include helpful color coding. These things make looking at code, on line or on paper, a lot easier. Reading poorly formatted code is harder than you want it to be so if your code is not well formatted then fixing that is a great first step.
Next I like to look at variables. I like to understand the names, especially any coding standards that are being used, and what they mean. Knowing that a variable is an integer as opposed to a double is important. Making sure that coding conventions (do integer variables start with an “I”) and being followed (is a variable a double but its name suggests an integer) is a good place to look for logic or runtime errors. Keeping an awareness of scope of variables is also important. Comments on variables and throughout the program can of course be very helpful. My attitude about comments is “trust but verify.” That is to say that I try to confirm that the comments describe the code that they say they describe. If they fit – great. If they are wrong – fix them.
I like to draw lines to highlight things like the beginning and end of a loop, a module, or the actions inside a decision structure. The spacing along may be enough for some but I like that line down the side of the page. It helps me visualize the scope and the nesting of statements and variable scope. This also helps me to study the code to make sure the start and end are logical and correct. Once you have all the scopes figured out you can start from the inside and work out or from the outside and work in. In practice, if the code is at all complex, you may have to read it both ways. Take notes of what is going on. It helps.
Equations require a close look. One has to understand both what the formula is supposed to do but that the variable types work the way the programmer intended. There is no magic “do what I mean” instruction. All too often the computer follows its own consistent logic when a programmer was hoping (or miss-assuming) some different way of doing things. It’s also important that the values that are returned are of the type that the method says will be returned. A reason that I find paper useful is to double check parameters between where a method is called and where it is created. Again modern IDEs can make that easier for you. While reading code in the IDE IntelliSense in Visual Studio or other autocompletion tools can make checking a lot easier without bouncing around the file. So a mix of online and offline reading can be very useful. Use the tool that makes the most sense at the time.
The big gun in reading code can be a debugger. Single stepping through running code, assuming you are trying to understand code that works, can teach you a lot about what paths are taken and show you where things are not going where you think they are going. This is a lot easier today with modern IDEs compared to reading binary code in light switches back in the day. Today anyone can run a debugger. And more people should!
So that is the basics. I’m sure I’m missing things that I do without really thinking about it. What advice do you have for someone reading code?