Why Learning to Program Still Takes Ten Years (And What to Do About It)

Every few months, a new course promises to make you a full-stack developer in a weekend. Bootcamps advertise job-ready skills in 12 weeks. AI coding assistants now autocomplete entire functions. And yet, the gap between a developer who writes code and one who engineers software remains as wide as it has ever been.

Peter Norvig made this argument in 1998. It holds in 2025.

The Difference Between Syntax and Judgment

Learning the syntax of Python, JavaScript, or Rust is genuinely fast. You can read and write basic programs within days. What takes years — a full decade by Norvig's estimate — is developing engineering judgment: the intuition to spot a race condition before it ships, to recognise when a simple SQL query will become a bottleneck at scale, or to know that the "clever" abstraction you just wrote will confuse every colleague who inherits it.

This kind of judgment cannot be downloaded. It accumulates through deliberate practice — building things, watching them break, debugging under pressure, reading other people's ugly codebases, and shipping to real users who find edge cases no test suite anticipated.

The cognitive science behind this is well-established. Expertise in any complex domain requires roughly 10,000 hours of deliberate practice — not passive repetition, but effortful work at the edge of current ability with feedback loops that correct mistakes.

What Modern Tools Change (and What They Don't)

AI coding assistants genuinely compress certain tasks. Boilerplate generation, documentation stubs, regex construction, and unit test scaffolding are all meaningfully faster with a capable LLM at your side. A junior developer today can be productive in ways that would have required years of ramp-up in 2005.

But here is the critical distinction: AI accelerates execution; it does not replace architecture.

When a system is under-designed, an AI assistant helps you build the wrong thing faster. It cannot tell you whether your service boundary is correct, whether your data model will survive a 10x growth in records, or whether you are reaching for a microservice when a well-structured monolith would serve you better for the next three years.

Those decisions still require the seasoned judgment Norvig described — judgment that comes from having made the wrong call before and lived with the consequences.

The Deliberate Practice Framework for Software Teams

If mastery takes ten years of deliberate practice, the implication for engineering teams is concrete: you have to design that practice, not just hope it happens.

A few approaches that actually work:

  • Code review as mentorship, not gatekeeping. Reviews that explain why a pattern is problematic — not just flag it — transfer tacit knowledge from senior to junior engineers faster than any course.
  • Post-mortems without blame. Dissecting a production incident as a team is one of the highest-density learning events in software. Make them routine.
  • Intentional exposure to unfamiliar domains. A frontend engineer who spends a sprint working on the data pipeline returns with architectural empathy that improves their frontend decisions permanently.
  • Reading production code, not just tutorials. Open-source repositories, especially mature ones with years of commit history, are textbooks on how systems evolve under real constraints.
# The delta between "it works" and "it scales" is invisible in tutorials.
# Only production traffic makes it visible.

def get_user_posts(user_id):
    # Works fine at 100 users.
    # At 100,000 users, this N+1 query
    # will take your service down.
    posts = Post.objects.filter(author_id=user_id)
    return [{"title": p.title, "author": p.author.name} for p in posts]

The code above is not a contrived example. Variants of it appear in production systems every week, written by developers who have learned the syntax but not yet accumulated the experience to feel the danger.

The Founder Lens: Hiring and Team Building

For SaaS founders and engineering leads, Norvig's argument has a direct hiring implication. Years of experience are an imperfect but non-trivial signal precisely because deliberate practice accumulates over time. A developer with eight years of varied, shipping experience has likely encountered failure modes — database migrations gone wrong, dependency hell, auth vulnerabilities, scaling cliffs — that a two-year developer simply has not faced yet.

This does not mean junior developers are not valuable. They are, enormously so. But it means team composition matters. A team of entirely junior engineers, regardless of how talented, is operating without the scar tissue that prevents known classes of mistakes.

The practical recommendation: every team shipping production software needs at least one person whose instinct is to ask "what happens when this breaks?" before the first line is written.

Patience as a Competitive Advantage

In a startup ecosystem obsessed with speed, patience sounds like a liability. It is not. Teams that invest in genuine skill development — that treat engineering mentorship as a product priority, not an HR checkbox — compound their capability over time. The ten-year developer on your team does not just write better code. They make everyone around them better, catch problems before they become incidents, and make architectural decisions that do not need to be rebuilt in two years.

The "learn to code in 21 days" framing is not just wrong about timelines. It is wrong about the nature of the skill. Programming is less like learning a keyboard shortcut and more like learning to practise medicine: the credential comes early, but the competence takes a career.

Source: Peter Norvig, Teach Yourself Programming in Ten Years (1998) — https://www.norvig.com/21-days.html


Why this matters for your project: Whether you are scaling an engineering team, evaluating a technical hire, or deciding how much to rely on AI-generated code, Norvig's core insight is a practical design constraint. Budget for the learning curve, build mentorship into your process, and treat engineering experience as the compounding asset it actually is. The teams that do this ship more reliable software — not eventually, but within the first year.