How to Read Code like a Book

The aim of these notes📝 is apply framework from Mortimer Adler’s classic How to Read a Book: The Ultimate Guide by Mortimer Adler to reading code. I am publishing it as an antithesis to the great essay Code is not literature.

Pavol Kutaj
5 min readAug 16, 2023

some books (code!) is to be tasted, other to be swallowed, and some to be chewed and digested

— Francis Bacon

  • Also, the debate code-as-newspaper metaphore is raging in “Coding blocks” formatting matters episode
  • You can watch Uncle Bob Explain this repeatedly in his presentations on functions
  • The point is to be able to navigate clearly between layers of abstractions and to be able to decide into which rabbit holes you want to jump and which are of no interest to you.
  • You should, I believe, however, not read code like newspaper even though the content of the metaphor is sound.
  • You should, rather, read code like a book, as per mortimer’s adler How to read a book

I call this an ElIAS (Elias is the Greek equivalent of Elijah). I’ve always be been working on pomodoro technique and always been doing stupid s*it during pomodoro breaks. One of the s*it I do my favorite is immediatelly and automatically switch to copying others people code. Just to train a bit of typing (dan luu velocity) but also to get to know my colleagues by their work (following linus’s “talk is cheap, show me the code” point).

Read like El-I-A-S: Elementary ⟹ Inspectional ⟹ Analytical ⟹ Synoptical

WHYs transcribe other people’s code

  • You get to generate ideas
  • You get to improve things
  • You get to lessons for free
  • You get to get rid of your imposter syndrome, mainly when copying code of senior gods
  • get over status signalling
  • get into fruits of work, creations, so to say

INTRO

  • Read Good Code
  • Read Bad Code, too!
  • Bad is maybe even more important; learn the art of critique
  • Steal like an Artist
  • when reading code via copying code
  • use comments like old-school margins with markdown syntax
  • once done, you extract that into dedicated notes if you have a notebook
  • read shitty code with love, not with fear, and, also, keep looking for gems in the mess
  • you will find them

Step#1 El: elementary reading

  • elementary is basic-literacy stuff
  • look briefly at syntax of the code, stop look at the weeds, the tiniest details
  • is this comprehensible at all ?
  • or at what scale ?
  • can I comfortably read syntax of this code (not the purpose, not the logic)
  • is about getting levels of comfort.
  • is about checking APIs, seeing hey these are the blackboxes I am using explicitly, nice
  • is about knowing those, maybe their guts, too
  • for example
parser = argparse.ArgumentParser(description="Tool for managing the {0}".format(tool_name))
parser.add_argument('--log-level', type=int, default=3)
subparsers = parser.add_subparsers(dest="subparser_name")
move_parser = subparsers.add_parser("mover", description="Moves files for a given customer")
  • this is most probably known stuff, but still, it is too to knows there may be syntactical unknowns hereb
  • E, is not just “do I understand this syntax”; but it is also “do I know these functions? dependencies? the functionality”
  • E looking at imports and hot the dependencies are used thorought the code, what is the center here ?
  • E if for exampe you are scripting the terraform deployment, do you kow the concepts, language and methods of terraform within python ?

Step#2 I: inspectional ⟹ check out the ass (aim+size+structure)

  • define the type/genre
  • define the aim
  • look at size
  • look at structure
  • taste the general quality, possibly authorship
  • looking at the ASS of code is part of its inspection
  • use MiniMap
  • A: Aim
  • S: Structure (fold all and see functions and classes if possible)
  • S: Size (see how large the module is → )

call hierarchy

  • get a better idea of what functions are being called
  • go the the main function
  • navigate to the fucntion definition
  • press ctrl+shift+h (call references)
  • see outbound calls from within the main()
  • you can also see through the layers of data abstractions if you open further references

folding

  • fold and see the structure with approximate size
  • get the aim — look at the filename — this is “profiling”
  • can you get relationships with other modules ? yeah from imports, difficult to see who is using this one
  • look at the time the first guess starts arriving
  • possibly, look at the call hierarchy of the main() — if there’s such a thing

Step#3 A: analytical ⟹ a little bit of no rush; rubberduck is your friend

  • Decomposition, zooming in
  • ideally have connection to logs or any observability or trace of a process
  • map that to the definition of code
  • cultivate the previsualization, the sensitivity for performance, but not only
  • but in analysis, if they are blocks you are also making sense of these blocks, don’t just handcopy, look for the shapes
  • draw these shapes, there are pairs of commands (in scripts that are not using functions)
  • there are sections marked with comments, any bad practice
  • In general, be a critique of code, like a literary critic, but don’t scoff, don’t think I can do better, don’t turn a writer into a “xxx”
  • However, your imposter syndrome will be decreased a lot, it is still open source
  • Also, no rush. I’ve visitted philosophical seminar on the reading of Hegel’s PhG and we’ve read a several pages in a semester
  • …and next semester another several pages and then another, the professor was reading this his whole life perhaps. But there’s no rush
  • there’s luxury no no deadline here. Have something that the duty and shield is in the order, not in the DONE. There is no DONE in programming
  • no DONE in learning, that is in thinking. The history is bottomless, best practice is bottom less, craft is bottomless, be fine with bottomlessness
  • not everything is a project, mainly with the cultivation of the relationship with the classics. Have internal bind there, profess.
  • This is where the famous technique of rubberducking occurs

Step#4 S: synoptical / dialectical

  • Adler used a biblical term to describe the reading
  • I am using a hegelian one, stressing tension instead of harmony, contention instead of consensus
  • A more polemical nature of this reading, where xp enters to shake things up a bit

SOURCES

--

--

Pavol Kutaj

Today I Learnt | Infrastructure Support Engineer at snowplow.io with a passion for cloud infrastructure/terraform/python/docs. More at https://pavol.kutaj.com