# Code as Vocabulary: Strategy for LLM Era

**Podcast:** Thoughtworks Technology Podcast
**Published:** 2026-06-25

## Transcript

Hello and welcome to the ThoughtWorks Technology Podcast.
My name is Alexei.
I am one of your regular hosts and I'm speaking to you from Sao Paulo in Brazil.
And this time around, we'll have a chat with Unmesh Joshi.
Hello Unmesh.
Hi Alexei.
Good to be here.
Perhaps I'd better let you introduce yourself instead of me trying to tell people who you are.
Yeah, so...
I'm a distinguished engineer at ThoughtWorks, and I spend a lot of time exploring coding and impact of LLM on coding while I write a lot of code.
Excellent, excellent.
It's great to have you with us today, and thank you so much for joining.
And the topic today is actually talking a little bit about...
What is code?
So an article of yours came out this last May, right, on martinfowler.com.
And we'll sure have a link to it in the show notes for listeners who haven't had a chance to look at it yet.
And so let's try to explore a little bit about that.
So these days, there's a lot of conversation about tooling, new development paradigms, methods, how do LLMs and the new advances change the way we develop, how we build.
you know, harnesses around the code we're writing and validations and all those kinds of things.
So, and even some of those conversations go in the way of code is not a commodity, code is solved.
So what made you go back to, you know, that most fundamental definition and question right now at this moment?
Maybe let's get a little bit of the why, thinking about those kinds of things.
Yeah, absolutely.
And as you rightly said, more and more people think nowadays that code is commodity.
And rightly so, because you see writing just like a few lines prompt and getting a whole system running for you.
For the last several years, I've been working on distributed systems and doing workshops and even consulting around distributed systems and also writing a lot of code around that.
And obviously, with LLMs and tools like Cloud Code and Codex and Antigravity and Cursor and others, I obviously used a lot of them while writing the code that I had to.
And I see that a lot of discussions happening on social media and around the perception that's formed is that code is...
just the syntax in a particular programming language that gets compiled and get built into an application.
I think the point that before you write even first line of code, there is a lot of context that's built in your head and that's important.
I mean, starting from understanding the broader context of the problem that you are trying to solve and how you are going to structure the solution.
A lot of that is very difficult to get right up front.
So you need to iterate over what you are trying to build and what we call as coding activity.
It's part of the whole process of trying to understand the problem and building a solution.
And all that still needs to happen.
even when maybe you are trying to describe something to an LLM.
And you still need to structure your thoughts.
You still need to think how you are going to structure the solution.
And then maybe drive or iterate or let LLM iterate over it.
So I experienced that while building.
I mean, even if I think distributed systems is not something that everyone builds every day.
So it's kind of a niche topic, but I think it helped surface these issues more prominently because the topic is so difficult.
And I think that's true even in any regular coding assignments we do.
for any of the business domains.
And I think everyone who has developed an application, a system, or whatever, can relate to this.
I mean, the thinking process is intertwined to coding and even the way we express it.
So I think that's easily relatable.
So when you start thinking about concepts, but then once you start making them more concrete, you...
get a new understanding of your own thinking and what do the abstractions mean and those kind of things.
So that is interesting.
And I wanted to go back to one thing you highlight in your article that I think is a key idea.
Because when we think about even this commoditization process, I think people are looking at...
the instructions.
Oh, this is just machine instructions, something that needs to be executable, right, or executed by a machine.
But in the article, you talk about two lenses or two ways of looking at code, right?
Instructions, but also connected to this thinking process.
So maybe you can elaborate a little bit on that and talk about this definition.
Yeah, I mean, two lenses that I talk about in the article.
One is obviously what everyone thinks code is, that you're telling a computer or a machine what to do.
But there is another important aspect of code and that's structuring your solution.
And in doing that, expressing your understanding of the problem as well as the solution you are trying to build.
And I think all the high-level languages provide you the mechanism to do that.
Object-oriented languages.
allow you to think of your problem and solution in terms of objects and functional languages allow you to do that as a composition of functions.
One of the other aspects is that a lot of times nowadays people think that if you just know English, because English is the new programming language, that's a very popular theme nowadays, but it's not correct.
to think that way, I think, because English, I consider more as a carrier syntax.
I mean, just so that you understand when I use some words and construct sentences out of those words, you make sense of that.
But when I, when, let's say, I talk about a consensus protocol using majority quorum mechanism and...
and maybe sometimes using quorum overlap and uses a concept of a term or a ballot and stable storage.
Now, the words that I used in here, someone who is not, someone who doesn't understand distributed systems and what this consensus is all about, it's very hard for that person to know what I'm talking about.
Or even if you take...
simpler examples of let's say web we talk in english about the verbs get post put and we talk about idempotency characteristic of put or using caching effectively for get all the words that we are choosing there they they have a very specific meaning in in those particular technical domains and When we say that you can describe your intent in English, one of the important aspects that's often missed is that it's possible only if you understand the concepts very deeply of what you are trying to do.
That aspect is very, very, very important.
Yeah, absolutely.
I think, I guess that's why mathematics had to, mathematics doesn't get created in English, right?
Or in those carrier languages, as you say.
So you need a more precise way of expressing things.
You made me think of, you know, years ago I worked with a retailer.
It was a data project.
So talking about their data architecture and these kinds of things.
The work we did made them realize that they had three or four different definitions for inventory or the word.
And depending on specific context, specific use and those kinds of things, it were very different things.
So I guess that level of precision and trying to convey that idea.
the code does help you make that concrete, right?
The other thing is formulas.
I remember years ago working on financial calculations formulas, and we thought we understood the algorithm when we were talking about that in our case in Portuguese.
But then when we sat down to write the tests and write the code, we would understand that, hey, actually we got it completely wrong.
So that's an interesting process.
Yeah, yeah.
No, and it's really interesting how a lot of times syntax of doing something and concepts of that particular topic, there is a correlation a lot of times.
And so, for example, if you...
If you're trying to parse something with a regular grammar, I mean, you need to understand regular expressions.
And regular expression syntax is very hard for a lot of people.
I mean, I found it very hard to remember.
Me too, yes.
Yeah.
But if you understand the concepts behind that, then I think LLMs are, I mean, they cut through all the syntax noise.
of a particular tool that you use for regular expressions.
But understanding that those concepts, I think, is very important.
And other thing that I found often miss, but is very important, is we all know domain-driven design, and it's very popular.
But the concept of ubiquitous language that domain-driven design talks about, I think it's...
It's an extremely important concept.
And a lot of times, what we call as act of coding is about building that ubiquitous language.
Like whether you do it intentionally or unintentionally.
Whenever you work for domains like, let's say, retail or finance or commodity trading or any of that.
And you write software for that.
in whatever programming language you are using, you need to choose words for naming methods and naming classes, naming modules, your APIs, and so on and so forth.
And you can't just choose random words when you name those things.
The words come to you based on all the discussions that you have with...
your stakeholders, with domain experts.
And there is another important, I think, interesting concept that I see is this ubiquitous language.
It's like building a shared vocabulary, right?
I mean, you use like inventory example that you talked about in any domain, there are so many words to name the concepts.
I think I take it back to a fantastic keynote at OOPSLA that Guy Steele gave in 1998 to OOPSLA conference.
And he was talking about what constructs a programming language should provide to be able to construct vocabulary.
And the way he described programming.
is an act of vocabulary building.
And that's exactly what we do.
And a lot of times what happens is that the power of higher level programming languages, which is essentially allowing you to build this vocabulary, if you just use a higher level programming language, We talked about two aspects of code, and the basic is instructing the machine.
And if we just use a higher-level programming language in a way to just instruct the machine, but not use its power to create the vocabulary, I think that's where all the problems in programming start showing up.
And another useful thing that I see, I mean, when I work with any client, you see that even when we say very well-established broader domains like, let's say, banking or retail, which have online presence for several decades and very mature software systems built for decades, 20, 30 years.
You still see that when you think of it as a software, as a vocabulary building, each bank and each business, there is a broader vocabulary, of course, of banking as a broader domain.
But there are dialects, like every bank, every retailer will have their own variations of those things.
And it's fascinating, right?
Because even when we say, English as a language, for example.
That's true for any spoken language as well.
In India, where I live, practically every 100 kilometers, there is a different dialect.
And every 500 kilometers, it's a totally different language.
And it's important, right?
You need to understand the importance of those variations and those dialects.
And I think that is one of the reasons as well that there is no universal product and there is no universal vocabulary for any particular domain.
And another very interesting aspect of it, I think, is that this vocabulary, it always gets built on the intersection of technology news and the business domain for which you are building.
building software, right?
Because there is no meaning for inventory.
I mean, there is a meaning for inventory.
But when you say that inventory getting represented for detail on the web, there are web-specific aspects that you need to deal with while representing that inventory and while working with that inventory, right?
So understanding that intersection and then building that vocabulary at that intersection.
is important.
And that also builds, I think, I'm not sure if I'm running ahead of the questions that you are going to ask.
No problem.
That vocabulary also forms the conceptual model, like a shared conceptual model that you share with your team.
And having a shared conceptual model is extremely important.
Because it allows you to read between the lines.
Because whenever you communicate, communication is, I mean, it's very difficult to communicate precisely.
Even when two people are talking to each other face to face.
Even then, you take cues from facial expressions.
You take cues from maybe some of the movements, hind movements that I'm doing.
And having that shared conceptual model helps you read between the lines when you speak about something.
And same is true when you code.
Having that shared conceptual model helps you code as per the expectations that you have from your stakeholders.
And with LLMs particularly, I think it's extremely important to have that.
shared conceptual model because LLMs are trained on the entire internet of data.
So when I say I want to build a web API, for example, or I say I want to build a consensus algorithm, which I do a lot while teaching distributed systems, there are so many variations and so many decisions that you really need to take.
LLM probably will take a lot of them and a lot of them that you really don't want it that way.
And that's where I think people talk a lot about context engineering and building harness around the code that's generated by LLMs to make sure that you steer LLM in the right direction.
But if you think of code as the conceptual model, which feeds into the vocabulary that...
that LLM uses.
It becomes, I think, extremely powerful because then your code itself acts as a fantastic context as well as harness for your LLM.
And I think all this, it's fascinating how like this concept of vocabulary building and domain design and now how LLMs how you are like seeing it again in the context of LLMs that all these concepts, they really help you.
I find it very fascinating.
Yeah, absolutely.
So I think you nailed it when you mentioned this conceptual model that needs to be shared, right, in the team as well.
And then what are the tools that you have for building this?
Because, you know, natural languages like English, Spanish, Portuguese, etc., they're not very precise.
They're not good tools for building those kinds of things.
And so you mentioned Guy Steele's keynote about the tools that...
higher languages have for building those kinds of things.
I mean, when you think about, for example, object orientation, it forces you to think about, you know, hierarchy of concepts, interactions, communications.
And I think everyone who has developed, you know, bigger applications can draw from their experiences, hey, I finally understood what I meant by that concept.
when I tried to fit that into a communication structure among different objects, or when I had to think about inheritance and how these things correlate to each other and those kinds of things.
The same with functional programming, for example, when you, you know...
What are the transformations that the data needs to go through from a functions application perspective?
So those ways of thinking, they help us build that model in a way that's better expressible as well and more precise, right?
Because then that helps with communicating not only to the machine, but among team members and even to LLMs, as you say.
No, absolutely.
And I found it again and again, even when working with LLMs, that programming paradigms, as you rightly said, and even going beyond programming languages, there are programming paradigms, which are broader, I think, when you say object-oriented or functional.
And they help you in your thinking a lot of times.
And like when I was building a small framework that I use for teaching distributed systems.
I mean, I was doing it in Java, but a lot of it I did, some of it I did with Enclosure and some of it I did in Kotlin and some of it I did in Golang.
And it was helpful.
For example, when I define a generic model that I want to use for constructing distributed systems, I...
I think of a process and I think of messages and network and storage.
And when I represent those as objects while doing that coding, I mean, just because I am well versed with, let's say, object-oriented paradigm, it shapes up my thinking about how I'm going to represent a process as an object in code.
And same is true with functional, right?
I mean, when I'm using Clojure and I'm doing a chain of processes over a set of data, if I know functional programming and I know how method chaining, for example, works, it helps.
Because I can definitely not do if I just stick to Java and fewer object orientation, right?
And that's the reason you see all the programming languages, they eventually become what you can call as multi-paradigm languages, right?
Because Java, which started just as pure object-oriented language, it has a lot of functional programming features nowadays.
And it's important to realize that the programming paradigms and even sometimes languages, they help you.
I also find it fascinating that whenever we talk of vocabulary and shared conceptual model, there is also a place for well-understood idioms and patterns.
And I see that when we talk of programming languages or paradigms, there is a well-established community around it.
And whenever you have a well-established community...
there are some shared idioms well understood within that community, right?
So Java is object-oriented, but when you code in Java, there are some well understood idioms of how to do certain things in Java.
Or when you do functional programming, there are well-established idioms in functional programming.
And if you're doing, say, Rust or Golang, there are some well-established idioms in...
in those communities.
And it's useful to understand and know those idioms.
And even when you are working with LLMs, I have found that they help me a great deal because I can steer LLM using right words in my respects.
Yeah, it's interesting.
And it goes back to what you're saying, right?
Because when you think about those idioms, they will bridge the conceptual understanding of the business that we have for that particular system to the common knowledge around the technology that's being used that many times materialize in idioms.
And then how does that connection between the business concepts and...
the technology implementation for doing what needs to be done needs to happen.
So that is quite interesting.
Unmesh, I also wanted to touch on a topic you have published about that connects to all of this.
So when we talk about building that model, that goes back to understanding what is it that we're building, right?
And the model...
does help a lot with that.
Not only understanding the business problem and the solution that we're building, but also that understanding of the technology solution that we're deploying.
And code definitely will serve that role of being the tool for that understanding and that knowledge.
So you have also talked about how important it is for teams to keep that understanding and that learning, both from an application development perspective, but also from a more technical perspective.
So how do you see that connection?
Oh, no, absolutely.
Absolutely.
And I think it has come back to me again and again, because in software, you know that every few years you build like another layer of abstraction.
I like to see abstraction in a way.
I think it was a sentence from a very nice book on organizational patterns.
It talks about why architects need to code.
But it says that abstraction.
is a controlled form of ignorance because you are intentionally ignoring certain details so that you can focus on certain aspects of your thinking.
But it's extremely important to understand what you are ignoring while thinking because even when you have layers and layers of abstractions and with cloud, you can almost cloud and containers and...
all the other things layers on top of physical machines a lot of times you ignore that there is a physical world that exists which runs on on actual power there is something called a cpu and there is something called as memory which is volatile in nature and any data that is stored there goes off if there is no power and then there is network and When there is network, there are physical distances that your message needs to travel.
And then there is physical limit of speed of light on anything that travels in a medium.
And then there are storages and storing anything is the slowest operation that you need to do.
And again, while I was working on distributed systems, I found this fascinating book.
called Understanding Software Dynamics.
It's written by a veteran Googler.
One of the things it starts with is that there are only four fundamental physical components that you need to really understand and CPU, memory, disk, and network.
And even when there are layers of abstractions, if you don't understand what's happening at the network and CPU and memory and storage level, It comes and bites you.
Understanding from that level to the layers above and layers above and that's how for any professional software developer or architect, it's important because I think the more you understand when to ignore details and when to care about details that are hidden by all these layers, I think that...
that's directly proportional to how successful or unsuccessful you are with what you are trying to build.
Yeah, absolutely.
But we need to choose, right?
Because abstraction is weak.
And every now and then, we need to go down layers of abstraction to fix things or understand what's happening or why the system is behaving in a specific way.
Another example you mentioned in a previous conversation we had is...
is about platforms right so we have seen a similar situation in which teams add more tools code generation abstractions other things without understanding what's really happening and that that will just bring a lot of variation or entropy to the teams and coordination problems and those kinds of things right so no absolutely and and i think code a lot of focus nowadays is on uh on talking about generating code but There are a lot of things outside of code which actually matter and they matter more.
And I'm seeing that with a lot of platforms that become complex over time, right?
Because when you build a platform and a platform that caters to a particular business, let's say a retail or trading or banking, the expectation is that a lot of teams should be able to reuse what is common and quickly able to build something on top of that platform, right?
But things like Conway's Law and they become more important than the actual code that you ship.
And Conway's Law, because the way you structure your teams, whether you like it or not, impact how your code ships over time.
And there is always this tension, I see, with platforms and the bigger the organization, the way you structure your teams, because they really are driven by how those teams are funded.
And then once you structure teams in a particular way, and a classic tension, right, whether if you always form teams based on the functionality that you are trying to build, then who owns?
the common platform and libraries right and if you if you form the teams based on the common components then how do you structure the teams who serve a particular function and there is always a common tension uh a tension in that and uh and these decisions they define or decide how you how you factor your your entire functionality into into components and services and how they talk to each other, how they depend on each other.
And all the complexity of software that gets built lies in there, not really with the code, right?
All these decisions which are higher-level decisions, I would say, which finally decide how your code looks.
But these are the layers at which the complexity lies.
I think there is no easy answer to this because real life is complex.
It's, I think, a mistake to realize that a lot of times because a lot of times what happens in the world of software is that whenever a new shiny tool comes up, it's very easy to think that that's an answer to every complexity and every problem that we have in life.
But that's not the thing because it's not that easy.
To go back to Fred Brooks, the classic mythical man monk, he talks of complexity at two levels.
He says that there is essential complexity and there is accidental complexity.
And any tool or solution that you choose, the focus should be to reduce the accidental complexity that's introduced because of a particular technology or a particular tool or a framework that you have.
But you need to acknowledge essential complexity that's part of your business or parts of the domain that you are trying to build.
Like by building distributed systems that I work a lot with.
When you talk of consensus algorithms, I mean, they are complex.
I mean, I can't trivialize that saying that, okay, if I use a particular tool or a particular method.
building consensus algorithm is going to become easy.
It's not.
But the focus should be to try to reduce that accidental complexity that comes in my way because of a particular tool.
But I acknowledge that, okay, I need to really take effort to understand why consensus algorithms are built the way they are and why they are implemented the way they are.
And I think it's...
equally important in any domain, any business domain.
Yeah, absolutely.
And that will require that understanding and having made a good choice of what to abstract and what to ignore and what not to ignore, right?
So it goes back to what you're saying.
Absolutely.
And Anun Mesh, how about the future?
So, I mean, because on the other hand, there is a lot of...
As we were discussing, LLMs do help a lot with understanding details that maybe we don't need to know exactly, or we can invoke them just in time, like knowing specific idiom or knowing specific syntax.
There is also a lot of boilerplate instructions that usually need to be generated and maintained and those kinds of things.
And we have seen LLMs help a lot with that.
I wanted to ask you maybe, what are some of the things we're working on?
Is it possible to work at a different level of abstraction or how specifically do you see advancements with the use of LLMs combined with those ideas or maybe what are you working on connected to this?
Yeah, so currently what I'm fascinated about and actually working on is using domain-specific languages with LLMs.
I'm fascinated because LLMs accelerate what I'm doing.
Domain-specific languages, we all know.
I mean, there is a very famous book written on this, and there is a lot of discussion about domain-specific languages.
But what I see, particularly with LLMs, is that all the...
LLMs are as effective as, I would say, the quality of the context that you build and the quality of the harness, which quickly identifies if there are LLMs diverging from what's intended.
And expressing that intent in the way you prepare context for the LLM as well as the harness for finding the deviations, that can very beautifully done.
with domain-specific languages because domain-specific languages, when you use certain words, and again, it goes back to the vocabulary discussion that we had, but with DSLs, there is a very distinct space of how you can arrange those words and what you can do with those is constrained.
And that, I think, works very well with LLMs because...
You don't ask LLM, for example, to generate a Java program or a web application.
You can give some examples and it's sometimes called as a few-shot prompting kind of thing that you give some examples of how your domain-specific language works and then prompt it to then generate code in that domain-specific languages.
I've not used it on the large scale projects, but whatever work that I do, I've had very good success with that.
So probably the future, and it's very, very difficult to predict, but probably the future is having more and more these DSLs to orchestrate working with LLMs.
That's fascinating.
So we'll be watching closely your future thoughts and experiments on that.
All right.
So we're almost at the end of the episode.
Unmesh, any final thoughts you would like to share?
Maybe, I mean, we talked a lot about some of the fundamentals of the role code plays in development, understanding and those kinds of things.
Maybe what are some of the principles that we'll hold even, you know, in the current...
big change scenario that you have for the industry or any advice you want to give people or any final thoughts?
I think some time back we published an article titled Expert Generalists and the characteristics of that expert generalist persona and we find a lot of those I mean the article was written based on experience we had with our artworks colleagues but all the characteristics of that expert generalist persona, I think it's going to thrive in the realm era.
Just being curious and understanding the fundamentals well and not limiting yourself to a particular domain.
I mean, all those characteristics, I think they are going to be essential, I would say, in the future.
All right.
Thank you so much.
Thank you so much for that.
Okay, and that brings us to the end of the episode.
Unmesh, thank you very much.
It was a great conversation, a great pleasure to have you with us.
And for all of the listeners, thank you so much for joining.
Thank you.
Thank you for hosting me again.
