saouri.ink
seedling

Understanding Isn't Free

I started programming professionally back in 2016, mainly doing web and mainly fiddling with everything I could get my hands on early to be exposed to as much surface area as possible (GraphQL, Python, Node.js), I was thinking in services not products and had not even realized that engineering is a utility not an end-goal. The idea was to build services and gain understanding of languages, frameworks and libraries while building these services and apps (again no product in mind), I did understand how callbacks work on Node and which HTTP methods to use in a REST API, how OAuth works (kinda) “WHILE” building these services, at that time I never realized that understanding could never not happen as a byproduct of building, the formula in my mind was simple: you build x with y, you understand how y works.

But what happens when you did not “build” the x, but “generated” x? On the vibe-coded to augmented workflow spectrum, there is no dot that ensures a full understanding of code since understanding is supposed to happen somewhere between the planning and the writing. It’s hard to construct a mental model of something when what you get is the “correct” final result.

What about reading the code post-generation: should that not fix this? I believe it depends on the blast radius and the intent: did you write this code to learn technology x? does this code require you to jump through three different layers to understand the data flow? is only the code necessary to understand the system?

For me, reading code after generation is like reading a book about a football match instead of watching the game highlights: a lot of unnecessary narration and noise, some yawning in between that will make you miss the important beats.

Instead, I find that writing more code helps. I do realize the irony. Not all code is critical, so one thing you can do is generate more dull code to help you understand your mission-critical code. This can take many shapes and levels depending on how much you want to get into that loop of understanding.

The simplest form is to generate an HTML artifact that “narrates” the change using Mermaid graphs, data flows, blast radiuses, assumptions and mental models, you know: replace the number of lines and function names with stuff you actually care about.

I also sometimes build quizzes around certain parts of the systems to make sure the mental image I have of these systems matches their respective realities. Try this: you will be very surprised by how much our own perception can diverge as these systems grow.

Building representations of systems in shapes outside code can also help “visual learners”: people such as myself blur out the niche tech details and see the big picture.

Another bottleneck that depends on the decoupling of understanding is verification: it’s easier to verify stuff you build by hand since your assumptions and constraints are on the surface. The less knowledge you have of the blast radius, the more time you should spend on verification, but … who got time for that?

Use more code, yes, same advice again. The main restraints historically on building verification systems for apps were priority and effort. Both these are less of a restraint now since: 1. like we know, LLMs perform better when they have something to verify against; 2. the effort required for building a verification system in the past was the same as building the system. That is not the case now.

Not all code should be treated with the same care as your “critical” code. We can now afford to build more verification code: build custom debuggers, build dev tool panels and data flow visualizers, slowly start tearing down that economics barrier that we were tying to expensive-to-build verification systems. It does not have to be. Vibe code the hell outta them.

Understanding was never an issue, it was a byproduct you got for free. But now code is “free” and understanding is the bottleneck. Invest in good verification systems, invest in ephemeral artifacts to help you build that loop, build throwaway prototypes to stress-test your mental image of the system or keep it up to date.

The above is mainly a confession rather than advice. I’m guilty of falling into that subconscious lookout for premature abstraction for short-lived artifacts.

Understanding is the investment.