Borrowing Fluency From Coding Agents
Agents let developers inspect and direct code in languages they cannot yet produce fluently, lowering language barriers without supplying ecosystem judgment.
Nearby Signal was my first substantial Swift project. An agent established the initial SwiftUI structure, CoreBluetooth scanner, package configuration, and concurrency model, giving me a working application to inspect from the beginning. Productive fluency developed through the project itself.
The implementation was legible. I followed the scanner, saw where Bluetooth work left the main thread, understood how immutable snapshots reached the interface, and traced why each inspector kept temporary signal history. I questioned boundaries, asked for alternatives, ran the results, and recognized when the structure no longer matched the behavior I wanted.
Reading and directing Swift came before writing it fluently unaided.
That asymmetry explains part of why coding agents make unfamiliar programming languages newly practical. They do not require complete expressive fluency before useful work begins. They put a concrete implementation in front of the developer, changing the task from recalling how to produce the language into understanding, questioning, and revising something that already exists.
Receptive And Productive Fluency
People learning another human language often recognize more vocabulary than they can produce unaided. Applied linguistics distinguishes this as receptive and productive knowledge.
In a study of second-language vocabulary, Stuart Webb found larger receptive than productive vocabularies when responses were scored for fuller knowledge, with a wider gap among less frequent words. When partial knowledge counted, the difference became much smaller. The measurement matters because recognizing a word, producing it from a cue, and selecting it during free conversation are different tasks.
The useful analogy is that production from a blank page requires retrieval that comprehension does not. A learner trying to speak must choose the vocabulary, construct the grammar, and recall the correct form in real time. A reader has the form in front of them and can spend more effort determining what it means.
Programming has a similar split. Productive fluency includes recalling syntax, library names, build commands, package layout, error-handling patterns, framework conventions, and enough idiom to assemble them into a complete implementation. Receptive fluency begins with concrete code. The developer can trace data flow, inspect definitions, compare an unfamiliar construct with a known concept, and ask a narrow question about the part they do not understand.
The two skills remain connected. Someone who cannot follow a language at all cannot responsibly direct large changes in it, while repeated reading does not automatically produce the ability to design and write a system independently. The gap matters because agents can now place useful work inside it.
Productive Fluency Used To Be The Entrance Fee
Before an agent could create the first candidate, someone had to know enough of the target language to make it exist. Documentation and examples helped, but the developer still had to translate a design into compilable syntax, choose the packages, build the project structure, and work through every missing name before they could inspect the whole result.
Programmers already used examples to reduce that burden at a smaller scale. In Two Studies of Opportunistic Programming, Joel Brandt and his coauthors observed programmers interleaving implementation with web searches to learn just enough, clarify existing knowledge, and retrieve details they did not consider worth memorizing. Coding agents extend that workflow beyond adapting one example at a time: the starting artifact can now include connected files, dependencies, interfaces, build configuration, and a working application to revise.
That made language familiarity a strong constraint on technical choice. A team might know that Swift fit a native macOS interface, Rust fit a small systems tool, or TypeScript fit a browser application, yet choose a less natural implementation because its existing language was the one it could produce reliably. The cost was not only learning the language eventually. It was paying that cost before the first serious experiment could begin.
An agent changes the order:
- State intent and constraints
- Inspect a concrete implementation
- Ask targeted questions
- Compile, test, and observe
- Revise
The developer no longer has to hold the target language’s entire productive vocabulary in memory before seeing the system. The agent retrieves syntax and conventions, the compiler rejects invalid expressions, tests expose behavioral disagreement, and the developer can concentrate on the smaller set of choices that need judgment now.
That shift operates at more than the line-of-code level. Writing a valid function and composing a complete project are different productive skills, just as writing grammatical sentences and organizing a book are different. A project requires structure, dependencies, interfaces, build configuration, sequencing across files, and enough continuity to survive incomplete states. Agents lend productive fluency at that scale too: they can assemble the first coherent candidate so the developer begins by evaluating a system rather than manufacturing every piece required to see one.
This is one mechanism behind the argument I made in AI Has Not Removed the Learning Gap: agents compress implementation knowledge more than the judgment required to shape a durable system. Productive language fluency is part of the knowledge they compress. Receptive fluency and engineering judgment become more valuable because they determine what happens after the candidate appears.
Code Is Unusually Friendly To This Shift
Programming languages provide feedback that ordinary language conversation often cannot. A parser can reject invalid grammar. A type checker can identify incompatible values. A formatter and linter can enforce many local conventions, while a test can express expected behavior without requiring the developer to remember how the implementation should be written.
The program can also be interrogated. I can follow a symbol to its definition, ask the agent to explain an ownership decision, compare two implementations, inspect package documentation, or run one path under a debugger. Each action turns a vague gap in language knowledge into a bounded question.
Program comprehension was already a large part of software work before generative coding. A field study of 78 professional developers found that developers spent an average of roughly 58 percent of observed time on activities classified as program comprehension. Software development has never been continuous code production.
Agents increase the importance of that existing work. They can produce the expression, but a person still has to connect the result to the surrounding system, decide whether its model is coherent, and determine what the available feedback has not checked.
Engineering Concepts Travel Better Than Syntax
Transferable engineering concepts made Swift inspectable beyond braces and function calls. Resource ownership, state transitions, asynchronous work, cancellation, interface boundaries, data identity, and failure containment still mattered even when their Swift expression was new to me.
An experienced Java, Go, C#, or Rust developer does not begin another language with no relevant knowledge. They already know questions that survive translation: Who owns this value? Which operation can block? What is shared across threads? Where does failure go? What contract will another component depend on? The target ecosystem may answer those questions differently, but recognizing the question is much of what makes the code reviewable.
This is narrower than professional breadth. In Breadth Got Cheaper. Depth Did Not., I argued that agents help one person cross into fields with different methods and standards. Programming languages often share more of their underlying problem than those fields do. The agent is translating established engineering concepts into another system of expression, while the developer checks whether the translation preserved the intent.
That makes language boundaries unusually permeable for experienced engineers. It does much less for someone who lacks the concepts being translated. An agent can produce and explain an actor, transaction, retry loop, or ownership type without giving the developer the judgment to recognize when the system needs one or when its guarantees are insufficient.
Readable Code Can Still Be Wrong
The receptive advantage has a dangerous edge. It is easier to understand code that exists than to produce it, but understanding what the code says is not the same as knowing what it should have said.
A generated function may be clear while omitting a failure case. A concurrency boundary may be easy to trace while violating a target platform’s runtime rules. The project may compile and follow familiar architectural shapes while ignoring an ecosystem convention that an experienced practitioner would notice immediately. No amount of line-by-line readability exposes an absent requirement by itself.
This is where the language analogy reaches its limit. A person can understand the literal meaning of every sentence in another language and still miss tone, register, cultural context, or an unnatural construction. A developer can understand every line in an unfamiliar codebase and still miss that the whole approach is unidiomatic, unsafe, or expensive to maintain.
In a qualitative study of 20 programmers using GitHub Copilot, Barke, James, and Polikarpova observed an acceleration mode, where programmers already knew the next step, and an exploration mode, where suggestions helped shape a solution the programmer had not already formed. Exploration is where the receptive advantage is most useful and where review is most uncertain: the generated candidate teaches the developer what could exist while also influencing what they think the answer should be.
Tests and types reduce that uncertainty only where correctness can be expressed through them. They are weaker when feedback arrives later through operational behavior, maintenance, security exposure, or the next requirement. An agent can explain common risks in the target language, but it cannot guarantee that the reviewer knows which local convention or missing question matters here.
The Work Must Fit The Comprehension Budget
The advantage disappears when generation outruns the developer’s ability to build a mental model. A bounded change in an unfamiliar language may be easier to understand than to write. An entire generated repository can be harder to understand than a smaller implementation written manually, because every file adds assumptions that must be reconstructed after the fact.
Useful agent work therefore has to fit a comprehension budget. The developer should be able to explain the model, follow the important paths, identify the contracts, and connect the implementation to observable behavior. Compilers, tests, linters, and agent explanations can support that work, but they do not replace it.
This also changes what it means to learn a programming language. Productive syntax practice remains valuable, especially for debugging and independent ownership, but it no longer has to precede every meaningful experiment. A developer can begin with a concrete system, learn the language through targeted inspection, and accumulate productive fluency while revising real behavior.
Language Choice Becomes Less Biographical
Programming-language decisions have often reflected the history of the people making them. Teams choose what they already know because unfamiliar syntax and tooling add immediate delivery risk, even when another ecosystem fits the platform or problem better.
Agents weaken that constraint. They make it more practical to choose Swift for a native Apple application, Rust for a small systems utility, or another language because its runtime, libraries, deployment model, and platform integration fit the work. The developer can evaluate a concrete implementation before becoming fluent enough to produce it unaided.
Familiarity still matters after the experiment. Someone has to own the application, diagnose failures, review dependencies, follow ecosystem changes, and recognize decisions that local tests cannot evaluate. A team should not choose a language merely because an agent can generate it, and one person’s ability to supervise a prototype does not create an experienced maintenance community.
Building the Swift application moved language learning into the development loop. Each concrete version taught me enough Swift to understand and shape the next. Agents lend the productive fluency needed to produce the candidate. Receptive fluency and engineering judgment turn it into software the developer can read, question, revise, and own.