Big no for retyping llm generated code by hand.
But a big yes for still typing code by hand, and not leaving it to the llm. Except it has to be the code generated by your brain.
That is what will create new neurons and new connections, which is what will keep away the cognitive decline.
And the constraint of not having to use llms will enhance creativity.
Actually, the constraints llms add to your code are more in number than the former. llms code in only the specific ways they've been trained on. So you won't ever come across of other ways.
Off the top of my head.. here's RubyQuiz.com [0] which I came across when I was learning ruby more than a decade ago. Looking at the many user-submitted solutions (you have to download the zip file!) you'll see completely different ways the problems were solved.
Sure, many won't be deemed efficient or standard by today's llm or rubocop checks, but looking at their code.. and retyping them and seeing them work.. was crucial in how I was able to think in Ruby for solving coding problems.
I did the same with Go too, with the "learn go with tests" guide [1].
[0] - http://rubyquiz.com/
So I always make sure I take a crack at doing what I want first. Then I ask for an AI review and it usually has a more efficient way to get the job done.
For example I had a working linear decay velocity boost function added to a godot scene and it's suggested refactoring actually reduced lines of code just today. So kind of happy when that works out, but yes I also applied the changes manually so I would grok them and hopefully remember it better.
This will cause cognitive debt anyway. As mentioned in https://arxiv.org/pdf/2509.21972v1: "When students rely on these outputs as a substitute for their own reasoning or critical engagement, the learning process is fundamentally compromised. Genuine learning requires the active construction of meaning, integration of knowledge, and reflective engagement with content. These processes cannot occur through passive consumption of syntactically correct but semantically hollow responses. Without this deeper cognitive work, learners risk mistaking linguistic fluency for understanding, thereby undermining the very goals of education".
Personally, I don't think we will ever be able to reconcile using LLMs and cognitive debt. Even before LLMs we were aware if it: we knew people moving to managerial/PM roles eventually get their coding skills rusted. Well, now we are all in those managerial roles...
This does not sound fun. It's better to work on your side projects with manual coding. You will learn more.
Retyping things is inefficient for learning. It's like trying to retype calculus solutions — you don't learn from it. Even if there is an explanation of why the code is written in such a way, you did not come up with it, and you don't know alternative solutions. It is a practice for memorizing, not for building your intuition.
A better option is to write it yourself first and ask LLMs for better options. They are pretty good at it, especially when you need to optimize hot loops.
I simply never ask LLMs questions specific to my codebase (except for finding what function/file does something, because that is annoying), and instead use generic questions.
Good advice yesterday, good advice today, and good advice tomorrow.
I don't remember if I read this advice or just intuited it myself (perhaps after some hard lessons), but it's a programming habit I've kept for as long as I can remember (I started coding in the 90s). If I feel rushed, e.g. someone looking over my shoulder, and I copy+paste something, it always leaves me with a sense of unease. It creates a memory & comprehension hole that sticks out like a sore thumb, even for seemingly simple snippets. You can't really be sure it's simple without stepping through it carefully, and simple can be deceptive because it's usually the interactions and assumptions wrt surrounding code that lead to surprises. Typing out code manually gives you time and space to consider the broader picture.
Lots of reactions here, but if it works for you then that's great.
For me I feel that LLMs have exploded (in a good way) my cognitive capabilities. I'm now the general of an army, rather than playing the role of a soldier. Of course that means that I lose the experience of being the lonely soldier, but it is a no-brainer tradeoff for me.
Anyway, I have to go now so I can push my car to the grocery store (so I don't forget how to walk), me and my giant calves will be back in a few hours.
All meant in good spirit. Keep doing what you're doing, thanks for sharing, and hope people are kind and only give good natured ribbings.
I share the author's sentiment. I also think it's important to fully understand a codebase I own. So much is naturally lost when you let LLMs generate code for you, and the mental model of what the added code does is one of the biggest losses. When you write code by hand, you build that model as you go, and it's enormously helpful later - when adding a feature, or when debugging behavior you didn't expect.
I've been trying to address this by telling LLMs primarily how the code should be structured, rather than only what it should do. Still, any design I hand to an LLM will be underspecified in one way or another (if it were fully specified, it would just be code), and the LLM fills those gaps somehow - which adds to the cognitive debt, slowly but surely.
Retyping LLM-generated code is an interesting solution. You'd certainly end up understanding the generated code better than if you merely reviewed it, but I doubt it produces a mental model as reliable as the one you'd build writing the code yourself. The longer you think, the better your mental model gets - and outsourcing the thinking to an LLM means thinking less.
That said, I've started to wonder whether I'm solving the wrong problem. Should I really insist on an accurate mental model of the code I own? We'd find it strange for a non-engineering manager to try to fully understand every piece of code their reports produce. If that's the right analogy, then as LLMs' agentic capabilities improve, maybe we should stop treating LLMs as tools that boost our own productivity as a software engineer and start treating them as independent agents we manage and steer.
In highschool, my history teacher's home work assignments were to write out the notes he created and handed out for us. Essentially the assignments were to read chapters from the text-book, then copy the notes by hand and hand them in. It seemed odd. But I think their is some wisdom to it. As you writing it out, you are slowly reading what you are writing... even if you do not mean to.
In my love(?)-hate relationship with "vibecoding", even I tried this approach. For a while it worked, though that "while" didn't last as long as the months OOP has been riding this wave. Though, the vibes have usually been off, so I wish I could keep both thinking of and writing that code which adds negligibly to shareholder value. I say "wish" because a part of me has definitely been hijacked, in much the same way as the addictive type of social media. Sometimes I feel like I need a serious intervention.
What I did is kinda similar, I downgraded to $20 plan and just ask questions and almost never let it write the code, and if I can I use the web ui like the good old days and not spend my CLI tokens.
Hah I was just thinking I should switch to colemak that I only let myself continue with for 2 months and re-type out all the domain (types, etc) for this project I'm working on
As an aside, back in the days of Stack Exchange I would always type out manually whatever answer I found to make sure I understood WTF I was adding to the system.
As someone who, at a point, would copy homework from someone else, copy book reports from online, and use the answer sheets to complete assignments, I can tell you this strategy is long known to accumulate and not prevent cognitive debt
> manually retyping LLM-generated code
This is just a miserable career of "paint-by-number" because people can't be bothered to have a creative thought about their professional work or programming hobbies.
Software developers think that they are being clever with these kinds of strategies to "keep their skills sharp", but unfortunately the entire industry knows about this, and especially the upper management who are already eliminating these assembly line, JIRA-ticket-taker software jobs en masse.
Do mathematicians and physicists put away the calculator and computer (this always reminds me of the last scene from Star Wars) and do the computation by hand? A physicist isn't going to manually invert a 10,000x10,000 matrix.
Exactly as we don't write machine code letting the compiler do that, now and in the near future we won't be writing high level programming language code. We are moving towards working on a higher level of abstraction.
When I ask a frontier model to write a loop 10 different ways in Python and TypeScript and test the performance of each using a 1,000,000 iterations, it isn't creating cognitive debt. For the time being, I'm still racking my brain asking the question, how does garbage collection affect the performance.
This is a new form of prayer for those who can't break their religious addiction to LLM code generators.
> As I manually type every single line of LLM generated code into my editor, I build up a mental model of how it works and fits into my existing codebase. If I don't understand an API or algorithm, I can stop to look it up, or just ask the LLM to explain it.
This is part of how I learned how to code! Well, sans LLMs. Instead of copypasta-ing code blocks from books, Expert Sexchange and Stack Overflow, I manually retyped everything, looked up what I didn't understand and changed what I could.
Sounds like a devious plan to turn me from a self diagnosed 10x developer (& Founder, CEO, Serial Entrepreneur) into a plain old 1x regular Joe.
I empathise with this. I run a little open source project called SmallDocs [1][2] which Claude/Coding Agent invokes to generate easily human readable Markdown documents (and render code files).
You can ask Claude to "sdoc me an annotated code walkthrough of this MR" and it will produce something like this:
https://smalldocs.org/s/Ju9GOmWZ0JXTtzqCVfgt1q#k=6HBrpcCjIu7...
I use this a lot to stay in touch with the code the LLM is producing.
[1] https://smalldocs.org [2] https://github.com/espressoplease/smalldocs
This is really the distinction between the mentality of a technical manager and an individual contributor.
Managers never got to write and internalize every line of code anyway. Arguably their essential skill is producing useful stuff without needing to do so. So is that 'cognitive debt'? When I use an agent to code, I do the same things: I validate the direction, organization, and core decisions, but delegate the details. It's an intentional calculation of risk, managing the scope of future problems if there's a failure of implementation somewhere.
It's a question of where you put the value of cognitive focus. I don't understand 'line by line' how my car's ICE works, even though it will likely impact me at some point, because while I might be able to fix it myself if it breaks, the likely applied solution will be to delegate that work anyway.
Seems like an ok solution, but what about doing something like the opposite? Write out the scaffolding and general shape of the code (classes, interfaces, function signatures), and have the LLM fill it in. That seems more important for understanding.
I'm taking a slightly different approach. I've started a project where I intentionally don't use agentic coding. I use LLMs for researcher and to learn, but write all the code by hand.
The goal is to maintain the taste, for lack of a better word, that I've developed over decades of programming.
Claude put me on to the concept "Étude", so I've taken to calling it my Étude project.
Print this article out and put it in the scrapbook.
File next to that 1970's era classic, "Prevent cognitive debt by manually retyping compiler-generated assembler"
I am also worried about "cognitive debt". I hardly remember what I had Claude do, even hours later. Back in May, I advised of a similar mitigation, citing the "generation effect" as the reason typing the code would make you remember it better:
> For your next ticket or feature, engage with your LLM as you normally would to produce a design and implementation plan, but with that plan in hand, make the mechanical edits yourself...You can expect this to improve your knowledge retention compared to merely reading a diff. You want to go slower now so that later you can go at all.
Retyping LLM code sounds absolutely miserable and soul crushing. Like hand copying the HTML produced by page generators... why would you do that to yourself.
It seems to me this is the same problem we previously had: how do we understand codebases we didn't write?
Creating while writing allowed us to build a mental context but in a unproductive way, it never scalled.
I believe we need to move onto a new way of reading codebases that go beyond reading line by line.
I know people have explored representing code in 3D spaces. I don't know the solution. But I believe that is the problem.
Generate code using LLM on a small project, then copy manually toward your big project. This reduces the context (and the cost) for the LLM and gives you many small projects where you can experiment ideas with more agility.
that's a great approach, the bad thing is that (at least I) will forgot my codebase anyway after two more projects. so i'm wondering if it worth the effort. i prefer to impose my vision on the code upfont and then rapidly check the my vision is respected rather than understanding every single line
This is what I'm doing right now to learn Electron, I essentially had Opus write me a tutorial to write the application I want to have, and I'm modifying bits and pieces as I go. It's been enlightening thus far, and the bot isn't always right so I still need to look up documentation on occasion.
You do that enough and I bet you'll be labelled "the slow one" in certain circles, so before attempting that as a junior make sure you have some measure of protection.
You are cooked if you can’t actually write better code than llm. Try reading some books or documentation
I got made redundant shortly before the release of LLM code generators, so I've never used one, but I did occasionally do this for short snippets from tutorials and suchlike.
This is not slightly comical, it is very comical. Side projects are not mandatory, if you are using them to learn something, asking LLMs to generate and for you to type it makes no sense - just do it on your own. If you want to offload tedious boilerplate part to LLM, then by definition no need to learn it as it is tedious, so typing it out is useless.
When I was younger and took over a codebase I open it up in one window and then type it back into another window. Not only did I catch/fix a crazy number of bugs, but I became a near expert overnight. Doing the typing would cause me to question everything, ask why we import something, why x is used and not y, etc.
I also tried where I would print out the code (with color) and then go read it with a red pen. Faster and similar results of forcing me to be able to read it enough to be "an editor" to the code.
And I have done the same for LLM-generated code and text, back in '23 this meant more taking their so-so output and then turning it into my own, but between now and then come up with a number of techniques to improve the AI output to more acceptable out of the gate so more learning than being inspired.
These are good techniques as it causes your own brain to rapidly learn the material, but no matter how good it is I have never met anyone else that does it so the real ponderable is assuming that everyone else doesn't do this and what does that mean?
Related, a writing advice I stole from Neal Stephenson is to write the first draft by hand. The thing is, there are a lot of small corrections where you kinda should change the text but nah, and if you already committed to copy the entire thing than you are already working at that sentence anyhow.
The Zed Shaw method!
I never had so little free time as I have these days. Most of my time is spent at work or with my lovely family.Love my family, and work is great.
The thing is that, probably like many of you, I love going deep in a side project, even if it lands nowhere. With so little time, working on them has become a very frustrating activity.
This is where I found my trap... do more with very little time by delegating to an LLM. You get dopamine shots, the feeling of achieving something but the cognitive dept is just crazy. So much that the activity becomes almost meaning less. After couple of months doing this, I'm not even sure it's a good use of this time. I get very little satisfaction on the long run.
I don't have a solution to this problem, not even sure there one. I think I have to accept that this is an activity that takes time, and only time gives the real gratification.
This resonates with me. The concept of cig it I've debt was something I've been experiencing but didn't have a name for it.
I think it is worth noting that not all code is equal... One could argue that adding a library is in some ways similar to copy/pasting code in as much as, one doesn't know what the code is doing, and yet that doesn't leave me with a sense of unease!
So it might be that as I'm working with an LLM there are parts (boring, as the author calls them) that are not worth "knowing" how they work, something uninteresting or that a correct output is all that us needed, I'm totally fine having the agent write that code, but the sections I need to know how they work, I think it might make sense to write those by hand!
Hard disagree, it's proven that its the actual discovery process that's makes us improve at tasks. Blindly typing will make you just good at typing.
I do think there is absolutely no way a learner should be using ai for code generation. I think code analysis is the only acceptable usecase.
I've used LLMs in a similar way and I'm reminded of learning to draw / paint.
At the very beginning stages you might be tempted to trace over an image but this builds a very shallow understanding. Instead you should quickly move onto replicating work you admire by sight. Consider the form, volume and values, conceptualise them in your mind and try to apply them in whatever medium you are using. This helps form your own mental model of the process. Eventually you can start using those techniques on original works.
I'm currently rethinking language learning too in a similar manner. Comprehensible input, shadowing. That sort of thing.
Lets prevent cognitive debt by manually retyping the assembly that is generated by our compilers...
I don't manually retype the code from pull requests of other engineers.
It's important to retain the what why and how as a team to the degree that development can be efficient, extensible, and maintainable. (And ideally a good devx)
Needing to manually touch every line of code is not scalable.
This was true 10 years ago. It's still true today.
Alternatively, what I tend to do after receiving generated code is a lot of asking "why?".
I've learned things I wouldn't otherwise have learned because I hadn't considered using the tools the LLM recommends. It's also a way to eliminate some hallucinating, given that critical questions are posed as unbiased as possible. For that, I also like to open a new chat with a different model and asking open-ended questions about a recommended tool I don't know much about, to double-check that the original LLM was likely correct in its recommendation in the first place.
Pair programming with the LLM is a better approach. You can take either role and even take turns. It’s slower but gives ample time to read everything and push back on decisions or receive feedback and review on your own decisions.
Jack Kerouac famously sat down and typed "Anna Karenina" on a typewriter because he wanted to feel what it was like to "write a great novel".
I don't know if retyping is the solution, but for me is clear that we need something additional to a terminal and a code editor. I envision a software that an agent can use and showcase to you how it did implement the changes and why. The same way a colleague would do, focusing on the important bits, then ending with the trivial stuff. Something in between pair programing and code reviews.
As others mentioned retyping is not fun. My approach is to let it write the code, but only in small portion. Not "implement this feature". But "open this file and make these changes". Each small change is easily reviewable and often times I end up asking it about better options and iterate a bit. Still feels like I'm in charge. Still feels like I'm learning stuff.
What's the right middle ground approach to this? I agree that inevitably my more advanced software approaches at work have been compromised by reliance on LLMs, especially given encouragement from management. Are there specific prompts/instructions people find that allow for learning and iterative development without slowing down the actual development cycle too much? I want to keep learning and keep my skills sharp but it feels like a losing battle.