Holding a Program in One's Head (2007)
The article highlights the cognitive processes in programming, emphasizing mental retention of code, the impact of distractions, and advocating for smaller teams and independent work to enhance creativity and understanding.
Read original articleThe article discusses the cognitive processes involved in programming, comparing it to the way mathematicians mentally navigate problems. It emphasizes the importance of holding a program in one's head, particularly during the early stages of a project, as this facilitates understanding and adaptability. The author notes that distractions can severely disrupt this mental process, and suggests strategies to enhance focus, such as working in long stretches, using succinct programming languages, and rewriting code for clarity. The piece also highlights the challenges faced by programmers in organizational settings, where collaboration can hinder individual understanding and creativity. It advocates for smaller teams and starting with manageable project components to foster better comprehension and innovation. The author concludes by critiquing traditional organizational structures that often stifle the unique cognitive demands of programming, suggesting that startups may have an advantage by allowing programmers the freedom to work independently and creatively.
- Good programming requires holding the entire program in one's head for effective problem-solving.
- Distractions significantly impact a programmer's ability to concentrate and understand their code.
- Working in long, uninterrupted sessions is more efficient than frequent short bursts.
- Smaller teams and individual ownership of code enhance understanding and innovation.
- Traditional organizational structures may hinder programmers' creativity and productivity.
Related
Laziness is the source of Innovation and Creativity
Laziness can spur innovation in programming by encouraging efficiency and problem-solving. Embracing laziness responsibly can lead to creative and efficient solutions, promoting a balance between productivity and creativity.
A dev's thoughts on developer productivity (2022)
The article delves into developer productivity, emphasizing understanding code creation, "developer hertz" for iteration frequency, flow state impact, team dynamics, and scaling challenges. It advocates for nuanced productivity approaches valuing creativity.
Code as Art
The article explores computer programming as an art form, emphasizing its aesthetic potential alongside functionality, highlighting examples like generative AI, esoteric languages, and contests celebrating unreadable code.
Algorithms We Develop Software By
The article explores software development methodologies that improve coding efficiency, emphasizing daily feature work, code rewriting, the "gun to the head" heuristic, and effective navigation of problem spaces.
Coding Just for Fun
The article encourages programmers to code for enjoyment, emphasizing creativity and personal projects. It highlights open source contributions during Hacktoberfest as a way to engage with the community.
There is certainly some truth to this. On the other hand, it's possible to become blinded to defects in code you've written yourself. You see what you intended for the code to do rather than what it actually does. Reading someone else's code, it can be easier to see what's really going on, since you just see what's there.
My advice on this would be: never be afraid, and even force yourself to, follow the chain of how a certain function is implemented in third-party libraries you are using. Set up your IDE to be able to click into functions, make that muscle memory, and perhaps even have a dedicated project you can bring up for your site-packages or node_modules. Don't just rely on documentation, see how things actually work a few levels deep. You'll gain a deeper understanding of the code you're using, as well as incredible practice for when you need to do this on an existing first-party codebase.
Oh, and if you can, get one or more large 4k monitors, and split your IDE into 4 quadrants! It's certainly possible to hold a codebase in your head on a small laptop screen, but being able to see the code you're working on alongside its dependencies and dependents makes this far easier!
I like to explain this as “hide the bad parts behind a good API”. Anything interesting is going to require “bad parts”, which just means the low-level, difficult work. From there, compose up and up until a high level orchestration is achieved. It works so much better than the bad parts being distributed everywhere! That’s what you’d also call a “leaky abstraction”
Break it up into a few or several smaller programs that interact through clean interfaces. Then you can keep one smaller, simpler program in your head at a time, then integrate them at the end once all the smaller programs are working.
Of course in a corporate setting it is much harder to do as you have code written in multiple languages using multiple patterns stored in different places, so often there is not underlying architectural thread to hold it all together.
Yes, this was in the microservices-heyday.
7. Don't have multiple people editing the same piece of code.
You never understand other people's code as well as your own. No matter
how thoroughly you've read it, you've only read it, not written it. So
if a piece of code is written by multiple authors, none of them understand
it as well as a single author would.
On some level it's true but it is also true that most of the world's code is in some sort of maintenance mode and the original developer is not always available. When I work on code that I think would be difficult to maintain I write a lot of comments to explain invariants that should be followed or anything strange. (Hmm, there are three different kinds of "row" talked about in this source file)If you have a front end-back end system and you want to do something simple like add a field to a form there's a strong case for a single developer or maybe paired developers to make all the changes to make that change happens as opposed to assign two developers (not paired) to communicate with each other about doing the task, or worse yet, assign two teams. You might have had two people build out the front-end and back-end systems but for sustainable maintenance one person should be able to ship a feature.
Just to elaborate on "start with a simpler subcase": you can even start with a single example and do what your code will be supposed to be doing automatically by hand. After your draft architecture stands, you can even hardwire what each component does for that one example to see if things fit together before implementing the general method for each component, which provides an opportunity for early integration testing that is priceless.
The current essay recommends building bottom-up primitives that serve as primitives or languages (DSLs) for the next levels. This is true, but you can do this upside down. For example, you can write code that looks like pseudo-code because implementations of functions you call do not (or not yet) exist. The code directly reflects how you think, and you worry about the implementation later. A special instance of that is API design, where you design interfaces without implementing them yet; you can then write client code and judge if the hypothetical API would be flexible enough, be easy enough to use, and be feature complete and orthogonal. When designing an architecture in a team with multiple people, you can use paper cards with an example piece of data that you pass from person to person, with each person "performing" a component. They can then check that they have what they need to carry our their task (otherwise there may be bad surprises when integrating components later).
I found that some people are more leaning "top down" and others more "bottom up"; I like to mix both styles, with system architectures designed top down and the core algortihms inside their components often being designed bottom-up, sometimes also top-down.
Ironically, looking only at the headline, one could say that abstraction enables one to solve problems without getting the whole problem in one's head, or problems bigger than what anyone can hold in their head, at least not at the same time, which kind of is the whole point made by SICP.
> Thanks to Sam Altman, David Greenspan, Aaron Iba, Jessica Livingston, Robert Morris, Peter Norvig, Lisa Randall, Emmett Shear, Sergei Tsarev, and Stephen Wolfram for reading drafts of this.
I used some tiny devices (e.g. Casio PB80 http://oldcomputermuseum.com/casio_pb80.html) as a kid to write small programs on in BASIC. It has only a single line of display and you had to sort of remember where things were to make your GOTOs work properly etc. This means that most of the program had to be in your head. You couldn't easily jump between things and see the whole thing as a single screen of text. I also remember reading that people like Ken Thompson wrote significant parts of the original UNIX on a line editor (ed). That would also mean that most of it had to be in his head in a semi parsed format.
Sure, with modern editors and IDEs, you can outsource that to the computer and focus on the more valuable stuff but I still wonder how much the grunt work of remembering things in detail is under appreciated in creative work.
Not only is that often false, but there are times when you can understand another author's code better than that author does. Like to see through it and why it cannot possibly work, while they are laboring toward that.
I remember the CTO of a big American bank telling me they didn't want to develop any software in-house. Their plan was to buy everything in. At the time I thought it was rather strange but having dealt with a lot of enterprise software since then I can see why.
And if you do it wrong (overengineering), you would need to learn not just one, but as many programming languages as there are layers...
I imagine a future world where 100% of coding and debugging is done by prompt not by editing code.
Unless, you know, it's automatically tested to hell and back.
Related
Laziness is the source of Innovation and Creativity
Laziness can spur innovation in programming by encouraging efficiency and problem-solving. Embracing laziness responsibly can lead to creative and efficient solutions, promoting a balance between productivity and creativity.
A dev's thoughts on developer productivity (2022)
The article delves into developer productivity, emphasizing understanding code creation, "developer hertz" for iteration frequency, flow state impact, team dynamics, and scaling challenges. It advocates for nuanced productivity approaches valuing creativity.
Code as Art
The article explores computer programming as an art form, emphasizing its aesthetic potential alongside functionality, highlighting examples like generative AI, esoteric languages, and contests celebrating unreadable code.
Algorithms We Develop Software By
The article explores software development methodologies that improve coding efficiency, emphasizing daily feature work, code rewriting, the "gun to the head" heuristic, and effective navigation of problem spaces.
Coding Just for Fun
The article encourages programmers to code for enjoyment, emphasizing creativity and personal projects. It highlights open source contributions during Hacktoberfest as a way to engage with the community.