Human languages require learning entirely new ways of expressing reality. Programming languages mostly express the same engineering concepts with different syntax. Once you master systems, architecture, data structures, and software design principles, moving between languages and frameworks becomes far easier than most people think.
Why Knowing a Programming Language Isn’t the Bottleneck
I’ve been studying Russian for 141 days.
Every day I open Duolingo. Every day I learn a few more words. Every day I get a little better at recognizing phrases when my girlfriend speaks Russian with her parents.
And yet, after months of effort, huge portions of the language still escape me.
I can hear words.
I can sometimes infer meaning.
I can occasionally follow the topic.
But I am nowhere near fluency.
What’s interesting is that software development doesn’t work like this at all.
I’ve spent my career moving between languages, frameworks, platforms, and codebases:
- Swift
- Objective-C
- Kotlin
- Java
- C#
- JavaScript
- TypeScript
- React
- React Native
- Node.js
- Unity
- SQL
- Python
Every time I enter a new ecosystem, people often ask some version of the same question:
“How long did it take you to learn that language?”
The honest answer is:
Usually not very long.
And that’s because learning the language was rarely the hard part.
The Beginner’s Mental Model
Many people imagine software engineering like this:
First you learn the language.
Then you become productive.
From that perspective, knowing Swift makes you a Swift developer.
Knowing React makes you a React developer.
Knowing Python makes you a Python developer.
But after enough years in the industry, you start noticing something strange.
The strongest engineers don’t seem particularly attached to any specific language.
Give them a new stack and they’re productive surprisingly quickly.
Meanwhile, some people can spend years working in a language and still struggle to build large systems.
Why?
Because the language was never the bottleneck.
Human Languages Are Huge
Russian contains:
- grammar
- culture
- history
- nuance
- emotion
- metaphor
- ambiguity
- social context
- regional variations
A single sentence can contain layers of meaning.
People imply things without saying them.
Words change meaning depending on context.
The same statement can be sarcastic, literal, affectionate, hostile, or humorous.
Human language is an attempt to encode reality.
Reality is complicated.
As a result, human language is complicated.
Learning Russian means learning an entirely different way of expressing and interpreting human experience.
That’s an enormous task.
Programming Languages Are Tiny
Now compare that to Swift.
Or Python.
Or JavaScript.
Or C#.
Programming languages are incredibly small.
Most languages contain:
- variables
- conditionals
- loops
- functions
- data structures
- error handling
- modules
- object composition
That’s basically it.
The syntax changes.
The concepts largely don’t.
Consider these examples:
if user.isLoggedIn {
showDashboard()
}
if (user.isLoggedIn) {
showDashboard();
}
if user.is_logged_in:
show_dashboard()
Different syntax.
Same idea.
The underlying concept never changed.
The Real Skill Is Conceptual Compression
After enough years, developers stop thinking in syntax.
They think in concepts.
Instead of thinking:
“How do I write this in Swift?”
They think:
“I need a cache.”
Or:
“I need dependency injection.”
Or:
“This should be immutable.”
Or:
“This operation should be asynchronous.”
Or:
“This is a state management problem.”
The implementation language becomes a detail.
The important part is understanding the underlying problem.
What Experienced Engineers Actually Learn
Over time, engineers accumulate a mental library of recurring patterns.
Not language patterns.
System patterns.
Things like:
- authentication
- authorization
- networking
- persistence
- synchronization
- caching
- concurrency
- dependency management
- state management
- event processing
- database design
- fault tolerance
Once you’ve solved these problems enough times, you start recognizing them everywhere.
Different companies.
Different codebases.
Different languages.
Same underlying challenges.
The names change.
The problems don’t.
Frameworks Are Often Vocabulary, Not Knowledge
This is where I think many hiring managers accidentally focus on the wrong thing.
They’ll ask:
“How many years of React experience do you have?”
Or:
“How many years of Flutter experience?”
Or:
“How many years of SwiftUI?”
What they’re often trying to measure is:
Can this person build software?
But framework experience is frequently a poor proxy.
A framework is often just vocabulary layered on top of existing concepts.
State management remains state management.
Dependency injection remains dependency injection.
Networking remains networking.
Database access remains database access.
The labels change.
The principles usually don’t.
AI Has Accelerated This Trend
This distinction became even more obvious after large language models arrived.
Today, if I encounter unfamiliar syntax, I can ask AI:
“Translate this Kotlin code to Swift.”
Or:
“Explain this React pattern.”
Or:
“Show me the equivalent implementation in Flutter.”
The translation happens almost instantly.
What AI cannot do for you is understand:
- system architecture
- business requirements
- tradeoffs
- scalability
- maintainability
- stakeholder communication
- project risk
Those are still the hard parts.
In other words:
AI is getting very good at translating vocabulary.
The vocabulary was never the bottleneck.
Why Senior Engineers Move Across Stacks So Easily
People sometimes look at experienced consultants and assume they’re unusually fast learners.
I think that’s only partially true.
What’s actually happening is that they already know most of the concepts.
Imagine a chess master learning a new chess notation system.
They don’t need to relearn chess.
They only need to learn the notation.
Similarly, when an experienced engineer enters a new stack, they’re often learning notation rather than fundamentals.
The difficult concepts were learned years earlier.
The syntax is just the wrapper.
What Actually Takes Time
Ironically, when I join a new project, the hardest things are rarely technical.
The hard parts are usually:
- understanding the business
- understanding user needs
- understanding stakeholder priorities
- understanding historical decisions
- understanding organizational constraints
Learning the framework is often the easy part.
Understanding why the system exists is the difficult part.
I’ve onboarded into projects where I understood the code within days.
Understanding the business took months.
The Bottleneck Is Not The Language
If someone wants to become a stronger engineer, I would spend less time obsessing over languages and more time studying:
- architecture
- distributed systems
- databases
- networking
- operating systems
- testing
- product design
- debugging
- communication
- business processes
Those skills survive technological change.
Languages come and go.
Frameworks come and go.
Platforms come and go.
The underlying principles remain.
Final Thought
When I study Russian, I’m trying to learn an entirely new way of describing human reality.
That’s hard.
When I learn a new programming language, I’m usually learning a new way to express concepts I already understand.
That’s much easier.
Which is why, after twenty years in software development, I’ve come to believe something that sounds almost backwards:
The least important thing about a software engineer is often the programming language they currently use.
The real value lies in the concepts they’ve mastered, the systems they’ve built, the failures they’ve survived, and their ability to recognize patterns that transcend any particular technology stack.
Languages are tools.
Understanding is the asset.