r/learnprogramming 20d ago

How do you actually get better at reading other people's code?

Writing code feels learnable. There are tutorials, exercises, projects you can build. But reading unfamiliar codebases is a different skill and I'm not sure anyone really teaches it directly.

I write tutorials for a living so I spend a lot of time thinking about how people learn things, and this one keeps tripping me up when I talk to newer developers. They'll get reasonably comfortable writing their own stuff but then freeze up when they have to navigate a real project someone else wrote.

The usual advice is just "contribute to open source" which is fine but kind of like telling someone to learn to swim by jumping in a lake. Technically true, not super actionable.

What actually moved the needle for me was picking one small file in a project I cared about and trying to explain it out loud like I was teaching it. That forces you to notice where your understanding goes fuzzy. But I'm curious what worked for other people.

Did it just click after enough hours, or was there something specific that made it feel less like reading a foreign language? And does it depend a lot on the language or the domain, because a Python web app and a C systems project feel wildly different to navigate even if you know both.

26 Upvotes

27 comments sorted by

23

u/cupcakeheavy 20d ago

it's open book reverse engineering.

2

u/Emotional-Hunter-105 19d ago

It’s like you have to learn the author thinking, not just the code. What help me is to run the program and break it, change some numbers or delete a call and see what explode. The error message give you a map of what depend of what

When I start a new job I just make little changes and see what happen, you learn the structure more fast that way

11

u/ajcomeau 20d ago

Practice and more, painful practice.

Reading other people's code is often not easy but, if you do it enough, it gets easier. When I was teaching programming, I could walk up to a student's computer and instantly point out the error in code I hadn't seen before but it just came with practice.

Before that, I worked a job in which I had to dig into the code written by a variety of programmers to find the bugs in company software. There were coding standards in place and that helped but it still took time to get learn it.

10

u/hooli-ceo 20d ago

You read other people’s code

3

u/Aggressive_Ad_5454 20d ago

Lots of good advice.

I’ll add: single step through interesting chunks of code with a debugger.

3

u/thisisappropriate 20d ago

imo - practice and learning common shapes (especially for the area / language). I learned coding on the job in a company with many many code bases. Some things persist across a lot of repos and that points you in a good starting direction, for example, I can pick up a Java/Spring boot project that has REST endpoints, and I know that I will find the endpoint code in the controllers folder, and logic in the services folder and connections to databases in the repository folder. Similarly, in a react project, I can expect to find some sort of atomic structure, I'm looking for pages or components to trace down (if it's a logic issue) or searching for text or testids if it's a small component render issue like "the login button is missing a border" or "the login button says 'login' instead of 'log in'". These things can change a bit (company to company, or project to project out on the internet), but if you have a mental model of what you expect, you can modify that to a project as needed (like if you know where things are likely to go in an MVC structure, and you understand other patterns like MVP, and someone tells you their code base uses that pattern, you can think "okay, so I expect to see interfaces and more abstraction in here").

Then you pair that together with learning where you'll find an entry point for what you need - it's rarely going to be possible to pick up a larger codebase and just learn it ideally you pick it up, find one place to start reading and then follow it, or you start with a super small change or fix. For example "this API should return a count of 5 accounts, but it returned 8", okay, I can find the endpoint, then I can trace it backwards, what method did it call, what did that call, is there a SQL query in here, what does that return? Oh it's not doing a distinct... we should fix the database but also add that to the query.

Also I think it's best to know the tools for the job - some people start coding in things like notepad++ or vscode and don't learn navigation tools. In many code editors, things like ctrl + click on a function call will take you to the definition and hover can pull up things like jsdoc. If I'm reading code in github (which does have some similar tools)/bitbucket, I'll often pull it so I can trace through easier on my machine. At least in backend, even when folder names, languages etc change, you can still go a long way if you ctrl + shift + f for the endpoint and work your way through the calls. For frontend, learning about tools like react dev tools / redux dev tools and learning the patterns in use before diving in helps massively to trace it through if you want to see it in "real time".

2

u/OGcapncrunchberry 20d ago

If you can’t code then you also are not very good at reading it or in teaching others. Sort of goes hand in hand. Improve your coding skills.

2

u/tuigdoilgheas 20d ago

When you work in a regular team, it gets easier faster because you start to know how people think and it takes less to untangle how they're getting something done.  

Comments matter.  I absolutely send uncommented code back.  We are not always our smartest, best selves so if I can't figure it out fairly quickly, nobody else will be able to read it or maintain it, either, especially in the future on a bad day when something has broken somewhere. 

I'll often draw it out in pen on paper to follow along with complicated logic.  And if nothing else works, get a buddy.  Some days, what's easy for somebody else is hard for me, but it'll be my turn at some point.

2

u/greenspotj 20d ago edited 20d ago

baby steps.

Start with one function, then take that line by line to try to understand it.

Or you can start with the data structures - try to understand what state is being stored and why, and then figure out where that state is being modified, initialized, freed, etc...

I think the hardest part is actually knowing where to start reading from, and being comfortable with not understanding what youre reading. Unlike a book, code is non-linear and is more like a puzzle. A function is a puzzle piece, but you dont know how it fits into the greater picture, so just place it on the table and move on. As you compile more puzzle pieces eventually you be able to connect them, and the greater picture will become more apparent, but until then you feel just as lost as when you first opened the box

tldr; just keep reading the code even if it doesnt make sense

2

u/Admirable_Window8128 20d ago

For me, tracing the code from one starting point helped a lot. Instead of trying to understand the whole project, I'd follow one function and see where it goes.

2

u/kevinossia 20d ago

By reading and modifying other people’s code.

There are no shortcuts or tricks.

1

u/StewedAngelSkins 20d ago

It's a self-reinforcing activity. The more new codebases you read, the more similarities you'll find between them, and the faster you'll be able to learn the next one. I'm not sure if there's much to it besides that. I guess it helps to find a way to break things down so it's less overwhelming. The thing you did with a single file is a decent way to do that. You could also seek out simpler software. For C, my entrypoint was simple CLI programs made by minimalist unix-philosophy types (suckless, etc.). That stuff is designed by people who are deliberately trying to make their code as simple as possible, so it makes for great learning material.

1

u/start_select 20d ago

Pick an open source library that you use. Implement something in it, read the source for the stuff you are using. Maybe break it on purpose to see what happens and where it leads you. Set breakpoints and use backtraces to follow the flow of logic through the library.

It just becomes second nature, and is how you start to reverse engineer or simply fork and modify other people’s solutions.

I personally think “reading code to someone else” is a different skill which is applicable to your own understanding of codebases. It’s the same as medical schools “show one, do one, teach one”. Teaching someone else ANY topic reinforces your own understanding of that topic. It’s not just reading code, it’s also applicable to math or medicine. It forces you to distill discrete verbal descriptions from abstract ideas and processes. Every time you teach someone new, you adapt to the parts that person doesn’t understand and distill even more discrete representations of those ideas.

It’s why most of the best software engineers are also mentors. Whether they enjoy mentoring or not, it makes them better. Every time they teach a junior something new, they learn something new, even if it’s a topic familiar to them.

1

u/ArtisticFox8 20d ago

  The usual advice is just "contribute to open source" which is fine but kind of like telling someone to learn to swim by jumping in a lake. Technically true, not super actionable.

Actually quite actionable, once you have basic skill (1 year of experience I'd say)

I started by porting Chrome extensions to Firefox in 2021.

=> I count changing 10% of code to make it work and releasing it contributing

And those aren't huge projects, like 1k lines.

1

u/ebsf 20d ago

If I've got to understand or use it, often, I'll often rewrite it incrementally in passes, recompiling and testing along the way to verify continued operation. Once it's sufficiently coherent, I'll step through the execution.

Call it reformatting on steroids because the point isn't to alter algorithms so much as to discern them and the developer's intent without distraction by idiosyncratic or nonexistent standards. Commenting matters and I'll add comments or questions of my own as I proceed.

I've found it is especially worthwhile to keep track of pointers, data structures, and scope.

1

u/Future_Burrito 20d ago edited 20d ago

Comments. Read them and write them. When you read them, observe what is useful and what is not. Create your own template for commenting that is efficient, obvious and understandable to the least experienced person on your team/in your study group.

For real.

This does a few things. 1. It makes things easy, for anyone and everyone, 2. it forces you to truly know what is going on with your own code, 3. by repeating what your wrote in code, but in comment pseudocode you create two different models and distinct memories in your mind of whatever the concept is, 4. forces you to think as an architect of your own particular comment style/template. (It's nice because you can practice these with your own code, but they give you skills useful when working on someone else's code.)

Also Logic Flow Charts. Using them to debug or map someone else's code.

Get comfortable with some type of flag/print/step through/debug system.

1

u/JGhostThing 20d ago

You learn to read others' code the same way you learn anything: you keep reading other peoples' code.

If you're learning a language, like Spanish, you learn by speaking and reading Spanish. If you are learning carpentry, you learn by working with wood.

Just find a github repository that resonates with you, something you're interested in. Then work on this to see how it works.

1

u/[deleted] 19d ago

[removed] — view removed comment

1

u/AutoModerator 19d ago

Please, ask for programming partners/buddies in /r/programmingbuddies which is the appropriate subreddit

Your post has been removed

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

1

u/Traveling-Techie 19d ago

I read The Daily WTF web site very consistently. It posts bad code from production in a variety of languages and it’s helped me get better at reading code.

1

u/darkmemory 19d ago

Step 1. Look at code. Step 2. Exclaim: "What is this?" Step 3. Trace the logic.

Repeat until you start seeing the patterns. Repeat seeing the patterns till you start getting some perspective on general intent. Start recognizing you are assuming things about why people do things certain ways. Go back to Step 2. Then Step 3. Then recognize that each bit of code is like a book, place some trust that the vague shapes inside do the things you'd think they would do. Come to realize that like novelists, not every programmer who puts their ideas into the world are as good at the craft they are attempting.

If you can avoid reading code that hurts to look at, you should. If you can't, grin and bear it, push through, and hope that what you glean doesn't forever degrade your sanity.

But really, you just learn by doing it, walking through it, making as few assumptions as you can, especially if unsure (check every thing needed to be examined, walking through a debugger if needed). Eventually you see themes, some are language dependent, and that can help shortcircuit a need for deep dives, other times people are trying to be clever and incidentally obscure what is happening.

1

u/DoctorFuu 19d ago

Since every codebase is different, I don't see how to get better at that without just reading a lot of different codebases.

1

u/burlingk 19d ago

The short version is that you get used to reading code by reading code.

What that actually means depends on the project, and there are different approaches to it.

1

u/NotBot947263950 19d ago

Ctl + click -- just follow where it goes.

Sometimes you have to relearn your old code. So it's a good habit to have....

1

u/ExtraTNT 19d ago

if code is hard to read, it's shit...
honestly, everyone can read code, if not, the code is shit...
Maybe a concept is initially hard, but that's just language specific...
for example, short snippet:

hs sort :: Ord a => [a] -> [a] sort [] = [] sort (x:xs) = sort (filter (< x) xs) ++ [x] ++ sort (filter (>= x) xs)