Why I Love Reading Other People’s Code And You Should Too

HateIt occurs to me, that many programmers hate reading code – c'mon admit it. Just about everyone loves writing code – writing code is fun. Reading code, on the other hand, is hard work. Not only is it hard work, it is boring, cause let's face it, any code not written by you just sucks (oh we don't say it, but we're all thinking it). Even your own code begins to look increasingly sucky mere hours after you've finished writing it and the longer you leave it the suckier it seems. So, why should you waste hours looking at other people's crappy code when you can be spending this time writing awesome code of your own? Weren't we just over this; give it a couple of hours and then come back and see if your code still looks awesome. You're never going to become a master of your craft if you don't absorb the knowledge of the masters that came before you. One way to do that is to find a master in person and get them to teach you everything they know. Is this possible – certainly, is it probable – not so much, you'd have to be extremely lucky. You don't really need luck though, we're fortunate to be in a profession where the knowledge and skill of all the masters is right there for us to absorb, embedded in the code they have written. All you have to do is read it, sure it might take you a bit longer without someone sitting there explaining it to you, but it's eminently possible. To put it in perspective, try becoming a great carpenter just by looking at a bunch of well constructed furniture.

I love reading code, I have always intuitively felt that you get a lot from it, yes it can be annoying and boring, but the payoff is well worth the effort. Consider this, if you wanted to become a great writer, would you focus exclusively on writing? You could try it, but you're not going to get far. It is an accepted fact that most great writers are also voracious readers. Before you can hope to write anything decent you need to read other great writers, absorb different styles, see what others have tried before you and feed your creative self. Your knowledge will slowly grow and eventually, your own writing will begin to exhibit some maturity, you will develop a 'feel' for it. Coding is no different, why would you expect to write anything decent if you've never read any great code? The answer is you shouldn't. Reading great code is just as important for a programmer as reading great books is for a writer (I can't take credit for this thought, it belongs to Peter Norvig and he is awesome, so take heed).

Even if all of this is unconvincing, there is one fact which is undeniable. Being good at reading code is important to your survival as a professional developer. Any non-trivial project these days will be a team effort and so there will always be large chunks of code you had no hand in which you have to work with, modify and extend. And so, code reading will likely be the most used and most useful skill you can have; better bite the bullet and get good at it – fast.

How To Read Code Like … Some Kind Of Code-Reading Guy

I can't tell you how many times I've seen programmers scroll up and down through an unfamiliar piece of code, for minutes on end, with a sour expression on their face. They would later declare the code to be unreadable crap and why waste the time anyway; we can just work around the problem somehow. I am not sure what the expectation was here, absorb the meaning of the code by osmosis, or maybe intensely stare your way to enlightenment? You don't read code by just looking at it for ages, you want to understand it and make it your own. Here are some techniques I like to use, it is not an exhaustive list, but I have found these to be particularly helpful.

Stare

  1. Try to build and run it. Often this is a simple one step process, like when you're looking at work code (as opposed to random code). However this is not always the case and you can learn a lot about the high level structure of the code from getting it to build and execute. And, on the subject of work code, you are intimately familiar with how to build your current project are you not? Builds are often complex, but there is a lot of understanding to be gleaned from knowing how the build does its thing to produce the executable bits.
  2. Don't focus on the details just yet. The first thing you want to do is get a bit of a feel for the structure and style of the code you're reading. Start having a browse and try to figure out what the various bits of the code are trying to do. This will familiarise you with the high level structure of the whole codebase as well as give you some idea of the kind of code you're dealing with (well factored, spaghetti etc.). This is the time where you want to find the entry point (whatever it happens to be, main function, servlet, controller etc.) and see how the code branches out from there. Don't spend too long on this; it's a step you can come back to at any time as you gain more familiarity with the code.
  3. Make sure you understand all the constructs. Unless you happen to be the premier expert on your programming language there are probably some things you didn't know it could do. As you're having a high level fly-through of the code, note down any constructs you may be unfamiliar with. If there are a lot of these, your next step is obvious. You're not going to get very far if you have no idea what the code is doing syntactically. Even if there are only a few constructs you're unfamiliar with, it is probably a good idea to go look them up. You're now discovering things about your language you didn't know before, I am happy to trade a few hours of code reading just for that.
  4. Now that you've got a good idea about most of the constructs, it is time to do a couple of random deep-dives. Just like in step 2, start flying though the code, but this time, pick some random functions or classes and start looking through them line by line. This is where the hard work really begins, but also where you will start getting the major pay-offs. The idea here is to really get into the mindset (the groove) of the codebase you're looking at. Once again don't spend too much time on this, but do try and deeply absorb a few meaty chunks before moving on. This is another step to which you can come back again and again with a bit more context and get more out of it every time.
  5. There were undoubtedly things in the previous step you were confused about, so this is the perfect time to go and read some tests. You will potentially have a lot less trouble following these and gain an understating of the code under test at the same time. I am constantly surprised when developers ignore a well-written and thorough test suite while trying to read and understand some code. Of course, sometimes there are no tests.
  6. No tests you say, sounds like the perfect time to write some. There are many benefits here, you're aiding your own understanding, you're improving the codebase, you're writing code while reading it, which is the best of both worlds and gives you something to do with your hands. Even if there are tests already, you can always write some more for your own benefit. Testing code often requires thinking about it a little differently and concepts that were eluding you before can become clear.
  7. Extract curious bits of code into standalone programs. I find this to be a fun exercise when reading code, even if just for a change of pace. Even if you don't understand the low level details of the code, you may have some idea of what the code is trying to do at a high level. Why not extract that particular bit of functionality into a separate program. It will make it easier to debug when you can execute a small chunk by itself, which – in turn – may allow you to take that extra step towards the understanding you've been looking for.
  8. The code is dirty and smelly? Why not refactor it. I am not suggesting you rewrite the whole codebase, but refactoring even small portions of the code can really take your understanding to the next level. Start pulling out the functionality you do understand into self-contained functions. Before you know it, the original monster function is looking manageable and you can fit it in your head. Refactoring allows you to make the code your own without having to completely rewrite it. It helps to have good tests for this, but even if you don't have that, just test as you go and only pull out functionality you're sure of. Even if the tests seem totally inadequate – learn to trust your own skill as a developer, sometimes you just need to go for it (you can always revert if you have to).
  9. If nothing seems to help, get yourself a code reading buddy. You’re probably not the only person out there who can benefit from reading this code, so go grab someone else and try reading it together. Don't get an expert though, they'll just explain it all to you at a high level and you will miss all the nuances that you can pick up by going though the code yourself. However, if nothing works, and you just don't get it, sometimes the best thing you can do is ask. Ask your co-workers or if you're reading open source code, try and find someone on the interwebs. But remember, this is the last step, not the first one.

If I was pressed for time and needed to understand some code reasonably quickly and could only pick one of the above steps, I would pick refactoring (step 8). You will not be able to get across quite as much, but the stuff you do get across you will know solid. Either way, the thing you need to keep in mind is this. If you're new to a significant codebase, you will never get across it instantly, or even quickly. It will take days, weeks and months of patient effort – just accept it. Even having an expert right there with you doesn't significantly cut the time down (this is what the last post in my teaching and learning series will be about). If however, you're patient and methodical about your code reading (and writing) you can eventually become intimately familiar with all aspects of the project and become the go-to man when it comes to the codebase. Alternatively you can avoid reading code and always be the guy looking for someone to explain something to you. I know which one I would rather be.

Seek Out Code Reading Opportunities – Don't Avoid Them

Code

We love to write new code, it's seductive cause this time we're going to get it just right. Ok, maybe not this time, but next time for sure. The truth is, you're always evolving in your craft and you're never going to get it just right. There is always value in writing new code, you get to practice and hone your skills, but there is often just as much (if not more) value in reading and playing with code written by others. You not only get some valuable tech knowledge from it, but often domain knowledge as well (after all, the code is the ultimate form of documentation) which is often more valuable still.

Even code that is written in an esoteric fashion, without following any kind of convention, can be valuable. You know the code I am talking about, it almost looks obfuscated, but it wasn't intended to be (for some reason it is often Perl code :)). Whenever I see code like that, I think of it this way. Just imagine the kinds of stuff you will learn if you can only decipher this stuff. Yeah, it's a major pain, but admit it, there is that niggling secret desire to be able to write such naturally obfuscated code yourself (no use denying it, you know it's true). Well, if you invest some time into reading code like that, you're much more likely to eventually be able to write it – doesn't mean you will write it, but you want to be ABLE to. Lastly, attitude is always paramount. If you view code reading as a chore then it will be a chore and you will avoid it, but if you choose to see it as an opportunity – good things will happen. 

Images by mafleen, Scott Ableman and LisaThumann

  • http://simplygenius.com Matt Conway

    I also find it helpful to walk through the execution of the code using a debugger. This lets you actually see what its doing as you read it, and usually leads to better understanding.

    • http://www.skorks.com Alan Skorkin

      Hey Matt,

      That’s a great tip also. I myself often prefer the old-school “printf debugging” :), but sometimes if you need to get serious you can’t help but crack open a real debugger.

  • http://www.davearonson.com Dave Aronson

    Don’t forget the value of *counter*examples. http://www.thedailywtf.com/ is great for this! :-)

    • http://www.skorks.com Alan Skorkin

      Hi Dave,

      Excellent point, but you don’t really even need “The Daily WTF”, especially once you get a bit of experience under your belt. There is so much mind-bogglingly horrendous code out there in the wild that you’re much more likely to run into that than into decent code (the experience is so that you can recognise when you see it :)). Thinking about it now, you probably learn more of what NOT to do from reading other peoples code, but as you say that is just as valuable.

  • Pingback: Tackling New Code Challenges « Triplett Web

  • http://www.seanplusplus.com/ Sean

    Awesome post as always Mr. Skorks!

    Can you give an example of a great piece of code to read that is not too gnarly for a noob?

    ( Something like the “Huckleberry Finn” or “The Great Gatsby” … but in code … )

    Cheers!

    • http://www.skorks.com Alan Skorkin

      Hi Sean,

      Well, that all depends on the language. If you want something really meaty, try looking at the SQLite source code. It is well written, well factored and well tested, but certainly not written in Ruby (it’s in C) :). There are also bindings for most popular languages which are smaller pieces of code worth looking at in the language of your choice. The other really good one to look at is JUnit.

      Here are some examples from recent personal experience – Ruby related. Ruby has a slew of different libraries and plugins, ones I’ve recently seen which I learned stuff from were the DelayedJob plugin, MongoDB Ruby driver, so feel free to give these a whirl. There is a whole bunch of others.

      If you want more you can try XStream, bits of the Spring Framework, the Git source etc.

      • http://www.seanplusplus.com/ Sean

        Thanks! I am gonna tackle one of these and will let yea know how it goes.

  • http://wwwhurriyetmax.com hurriyetmax.com

    Excellent point, but you don’t really even need “The Daily WTF”, especially once you get a bit of experience under your belt. There is so much mind-bogglingly horrendous code out there in the wild that you’re much more likely to run into that than into decent code (the experience is so that you can recognise when you see it :)). Thinking about it now, you probably learn more of what NOT to do from reading other peoples code, but as you say that is just as valuable.
    +1

  • http://acquia.com Jacob Singh

    Nice piece. I think the frustration in reading code comes from not understanding what it is supposed to do. We silly humans mostly hate stuff we don’t understand. If code is well documented (not at a method level, but a class or project level), or I at least have a chance to hear the “why” of certain decisions / architectural patterns, I’m more apt to enjoy the experience and get more out of it. But then I’m a “big picture” learner and need to know the motivations, inspirations, ruminations before I get the fascinations.

    Best,
    J

    • http://www.skorks.com Alan Skorkin

      Hey Jacob,

      I am like you in that I need the big picture, but I often find that I derive a lot of satisfaction from working out on my own why some high level decisions were made. It often takes a lot longer to get tot this point and the path is riddled with frustration, but that “aha” moment in the end makes it all worthwhile.

      • http://www.seunosewa.com/ Seun Osewa

        Since there are only 24 hours in a day, I suggest that coders should start commenting their code more intelligently instead of expecting us to struggle through things.

        • http://www.skorks.com Alan Skorkin

          Hi Seun,

          I am a big believer in self-documenting code. I few strategic comments here and there are ok, but otherwise the code should tell the story by itself. When code is written in this fashion, too many comments actually makes it harder to read. Of course, there are plenty of people out there who don’t believe in this philosophy, in which case comments and a lot of good tests really help.

          • http://www.seunosewa.com/ Seun Osewa

            Self-documenting code makes it clear to the reader what you’re doing,
            but it doesn’t help with figuring out why you’re doing what you’re doing.
            It’s no substitute for high level comments at the class or package level.

  • Sebastian

    > (for some reason it is often Perl code :))

    You’re an idiot and smiling won’t help

    > Now that you’ve got a good idea about most of the constructs, it is time to do a couple of random deep-dives.

    Some of these items really don’t seem much different from staring at the screen for a while.

    The bottom line is that code reading takes practice. You can usually sift out novice programmers by their ability to read and debug code that is not their own.

    • http://www.skorks.com Alan Skorkin

      You know, I considered not approving this comment, I take exception when people resort to personal attacks, but since it was directed only at me I decided to let it go. Maybe I should write about the value of having a sense of humour.

      I am presuming you have a much better list of tips on how to get better at reading code, that you’ve compiled previously and shared with everyone? I mean, you said yourself that code reading takes practice so how does one go about practicing, judging by your tone you must have dozens of efficient and helpful ways of doing so. If you do, please share and I will take my hat off to you.

      You can also usually sift out novice programmers by their lack of gray hair and wrinkles. The point is that everyone is a novice at everything at one point or another, so how does one go about becoming less of a novice. If someone needs to become a better runner, is it really helpful to tell them to do more running? Aside from the fact that it is obvious, there is the question of how much more running, when should they run, indoor or outdoor, track or cross-country, sprints or marathons, fast or slow etc. I try to share my opinion constructively, how about yourself?

    • http://www.davearonson.com Dave Aronson

      Face it, some languages are just more conducive to opaque code than others.

      1) Perl hides a lot of things behind its abstruse standard variable names. (Those who aren’t familiar with them, one list is at http://affy.blogspot.com/p5be/ch12.htm — tell him I said hi.)

      2) Even these can often be completely omitted from the call, so someone who doesn’t already know exactly what’s being referenced *and* where/how it’s set, has no clue how to find a critical value.

      3) Then there are the subtle differences between evaluating the very same expression in scalar versus list contexts.

      4) Sometimes it can be difficult to figure out which kind of context you’re in at the time!

      5) As Larry Wall himself likes to say, there are many ways to do it, whatever it is you’re trying to do in Perl. By itself that’s often a good thing, but it means all the more “ways to do it” that you haven’t seen before when reading code that does that functionality.

      That all said, though, a GOOD Perl programmer certainly CAN write clear and comprehensible code — but Perl does not actively encourage it, and in fact seems to encourage the problematic extreme terseness. By contrast, IMHO, Java is often overly verbose, and Ruby strikes an excellent balance. YMMV.

      • http://www.skorks.com Alan Skorkin

        In this case my mileage is the same, you have expressed my own thoughts exactly.

  • http://chase.com Hugh Jamieson

    This hits me where I live, Alan! I am on a team of a dozen pretty crazy java dudes and we have written 3+ years of a system, so there is tons and tons of LOCs. It is so hard to take time from your assigned iteration deliverables to look at what everybody else is doing, but it may be the only way you can contribute to a package you did not write. My biggest challenge is trying to understand the code beyond the language, i.e. wtf is this code doing with the data and why. For much of our code, intimacy with the model and the business requirements is key to understanding why the code is what it is. Point I am making here is that I use the comments I find in the code almost as important as the code, and I rate a developer more on those little goodies between /* and */.

    Thanks for this article!!

    • http://www.davearonson.com Dave Aronson

      Re taking time from your assigned deliverables, one place I worked had a Subversion post-checkin hook to send a diff to all developers on the project. We were all expected to at least take a brief glance at it. I don’t recall learning any particular interesting general techniques that way, but it did prep me for using certain local libraries when I needed to — and I spotted several glaring bugs. (Yes, Alan was right, there’s plenty horrible code out there without TheDailyWTF… but it’s still amusing.)

  • Randy Arvizu

    Well, done. Excellent suggestions. Number six, writing tests, is an extremely powerful and effective way to understand code. Not only does it force you to understand functionality, it often reveals structure and dependency.

  • Pingback: Dew Drop – May 20, 2010 | Alvin Ashcraft's Morning Dew

  • Muhammad U

    This post is actually very eye-opening and encouraging for me.

    I have almost never read code so far because I still am “learning” the skills and syntaxes of the languages I’m getting into. This actually is something I never thought about. Thanks for the post, helps a lot and I wrote a longer essay-like comment on my blog: http://bit.ly/ayU3oF

    I like the Perl comment in there, aha!

    • http://www.skorks.com Alan Skorkin

      You’re very welcome, I am glad you found it useful.

  • http://tudormunteanu.com Tudor

    I always thought that reading code is useful, but you did a pretty good job of expressing my hunch. As a Python programmer, reading code can be very fast.

    I’d add one resulting benefit of writing code: it helps me to write more readable code. Finding a lot of WTFs in someone’s code makes me think “hey, I should NOT do this too”.

    • http://www.skorks.com Alan Skorkin

      Exactly right, I often learn more from bad code than I do from good :).

  • http://hdragomir.com Horia Dragomir

    Oh, yes!

    Judging the number of “ah-ha!” moments I’ve had while reading other people’s code, I’m definite that this was the top contributor to my evolution as a programmer.
    And not only because of constructs, but mainly because of the way other people had organized their code before me.
    To paraphrase: I was what I expected, but in a shockingly cool way!

  • Julio

    You’re an idiot and smiling won’t help

    haha
    best comment ever!

  • http://nikhilkardale.wordpress.com Nikhil Kardale

    Those are some very good points. I’ve had lots of occasions when I had to acquaint myself with existing codes when I was a newbie in this field. Though I think I did a fair job at it, it would have been so much helpful if I had read this sort of article then!

    You’re basically right, software development is not just about writing good code, its also about getting inspired from and adapting to someone else’s code. Reading good code (and also learning what not to do in it as Tudor pointed out in the comments) is part of the education in this line of work.

    I especially liked the analogy with carpenters and good literary authors.

  • Trung Le

    Point 2 is an important tip in code review. Having a high level understanding of the code is the goal of code reading. I often find myself questioning the coder intention for every line of code. No one started out with the intention of writing bad code. Why would the previous developer wrote a bit of duplicated code? There could be two developers involved, with the later wanted to add a “similar” function in quick-and-dirty way. If your project have a good check-in policy, you can pretty much tell a story out of the check-in comments. All of a sudden, reading code becomes a fun activity. It actually tells you some story, the story of its evolution.

    The rest of the tips are all good tips, just don’t forget the ultimate goal, to own the code as if it is your own. Then you might stop cursing, and try to “love” the code.

    • http://www.skorks.com Alan Skorkin

      Hey Trung,

      I completely agree, you always want to get to the point where you feel like you were the original author of the code. You almost never get there unless you actually did write the code yourself, but I think it is a worthy goal to aspire to.

  • http://droope.wordpress.com droope

    Yeah. What I do, most of the time when working with foreign code, is to do some echos. See what info is there.

    I like debugging foreign code, it’s like reading a spell written in Quenya. :)

  • nickels

    I Enjoy your blog, thanks!
    Reading code has definitely been my #1 method of learning!! Been chewing on the quake3 source lately, amazing stuff (albeit C with structs)!

  • Danny Armstrong

    I’d love to see a blog post, article, entry, screencast or wall graffiti of someone doing a code review on a piece of open source code. It would put the points mentioned in this article into practice.

    If nothing else it could tell us that we are not alone in being dumbfounded and confused on a regular basis.

    • http://www.skorks.com Alan Skorkin

      Hi Danny,

      I hear you, I will have a look around and maybe do something like this for a smaller ruby gem. Let me have a think on it.

    • http://davearonson.com Dave Aronson

      Danny, check out http://www.thedailywtf.com for a daily dose of dumbfounding dirt! (This message brought to you by the American Amalgamated Association for the Advancement of Assonance and the Alliterative Arts.)

  • Pingback: Lire le code source… « The World is mine

  • Nick

    Great article. I just wanted to name-drop the book “Coders at Work”. My favorite part of that book is when Peter Siebel asks some prominent programmers how they would approach an unfamiliar code base.

    • http://www.skorks.com Alan Skorkin

      Yeah, it is a good book, I’ve given it a browse a couple of times. Talking about Peter Siebel, I’ve recently been looking at Lisp a little bit which led me to his earlier book “Practical Common Lisp”, also seems like a great resource from the little I have seen so far, small world and all that :).

  • Pingback: Дайджест недели, 15 октября « сообщество программистов

  • Nikhil Prabhakar

    Nice post!

  • Pingback: روابـــ(10)ــط « الطفرة

  • Pingback: PDB style function backtrace in python using Inspect module. | Ashish Yadav's Weblog

  • Pingback: 阅读优秀代码是提高开发人员修为的一种捷径 》CrazyCoder

  • Pingback: 乱象,印迹 » 【翻译】我为何爱读代码?你为何也应当爱?

  • http://www.luanxiang.org/blog/ Yurii

    I grant it very important to read other’s code, but article&books about it is so few. Thanks for Skorkin’s post, I really like it. Besides, the pictures are so much fun. So I’ve made a simplified-Chinese version of it:
    http://www.luanxiang.org/blog/archives/1092.html

  • Pingback: 阅读优秀代码是提高开发人员修为的一种捷径 - Wang Jiang's Blog - Code is poetry!

  • tanvir

    Hey
    From my professional experience and academic career, I think best fitted article. Thank you a lot.

  • Pingback: Guidelines For Working With External Code Libraries | Ruturaj Pradeep Kohok | Your Web Advisor

  • Pingback: Guidelines For Working With External Code Libraries | Web Information Share

  • Pingback: Guidelines For Working With External Code Libraries « Your Web Design Studio

  • Pingback: Guidelines For Working With External Code Libraries

  • Pingback: 阅读优秀代码是提高开发人员修为的一种捷径 - 博客 - 伯乐在线

  • Pingback: 阅读优秀代码是提高开发人员修为的一种捷径 | Qindamoni

  • Pingback: 请少用google | Ruby迷

  • Pingback: 阅读优秀代码是提高开发人员修为的一种捷径 | 逝水年华

  • Pingback: 阅读优秀代码是提高开发人员修为的一种捷径 | 岭南六少 - 一朵在LAMP架构下挣扎的云

  • Pingback: Google Reader分享 » 请少用Google – Look At the Code!

  • Pingback: Guidelines For Working With External Code Libraries |Layout to HTML

  • Pingback: Guidelines For Working With External Code Libraries |Layout to HTML

  • Pingback: 海上日志 生命诚可贵 | Rebornix

  • http://www.facebook.com/blz777 Anton Petrov

    Excellent article and very inspiring! (bow) Thank you!

  • Pingback: Programming | Rahul's Work

  • Krell

    Thank you for the advices :)

  • mizal

    Nice article. Thank You. One thing that I would like to add is the tools use to navigate/browsing the source code. The right tool playing important role in navigating and understanding the source code in much more efficient and faster.

  • Deepak Agrawal

    very intersting article. Thanks for the post !!

  • Pingback: Це не так просто – розуміти. | Блоґ одного кібера

  • Pingback: ActiveMQ源码学习1:从源码中找寻设计模式的踪影 - 开发者 - 开发者

  • Pingback: 阅读优秀代码是提高开发人员修为的一种捷径 | z36ker

  • Pingback: Why I Love Reading Other People’s Code And You Should Too | Megan Taylor

  • Pingback: 阅读优秀代码是提高开发人员修为的一种捷径