TypeScript, C# and Turbo Pascal with Anders Hejlsberg
2170 segments
Why was it called Turbo Pascal?
>> Because it was fast. This was when Audi
had their Quattros and their turbos, and
this thing was fast and super
interactive.
>> When you started out building C#, what
were your design goals?
>> We knew we wanted to build an
object-oriented language. We wanted
managed code or bytecode so we could
target different runtime environments.
We wanted garbage collection and
exception handling, but also things like
a unified object system.
>> What do you think made TypeScript this
popular? Absolutely because of the
better tooling. We were totally right
there that added an erasable type system
and then using that to enable great
tooling is where the productivity boost
is realized.
>> What is your take on either modifying
existing languages for AI usage or
coming up with a language that is more
suited for AI agents to use? Well, my
flip and answer there is
Anders Hejlsberg is one of the biggest
living legends in the tech industry.
[music]
He created Turbo Pascal, Delphi, C#, and
TypeScript. The impact he has had on
programming languages and developer
tools is immense. Today with Anders we
discuss how C# might have not been born
if [music] it was not for the Sun versus
Microsoft lawsuit over Java. The
behind-the-scenes story of TypeScript
and why open-sourcing it was a [music]
huge deal inside of Microsoft. What he's
learned from 40 years of designing
languages, including why IDEs and
programming languages go hand-in-hand,
and many [music] more. If you want to be
behind-the-scenes look at how three of
the most used programming languages in
history got built and how AI might
change our usage of programming
languages, this episode [music] is for
you. Before we start, I'd like to
introduce our presenting for the season,
Antithesis. A definite trend that I'm
seeing across the industry is a lot more
focus on testing, unsurprisingly thanks
to AI. We know that software is hard to
test, and we also know that AI is making
it worse. Thanks for producing
increasingly more code and more complex
code. The bottleneck is becoming
reviewing the code, testing it, and
trusting it. Or is it? We tend to think
that code reviews are the bottleneck
because you cannot scale human reviewers
with token spend. But the problem
actually goes beyond code view. Really,
it's about verification. We know that AI
cannot verify itself. To verify the
correctness of AI generated software, we
would need to catch issues that
traditional tests miss, including issues
that we did not even think of in a code
base that is changing at superhuman
speed. Oh, and we need to do all of this
before deploying to production. The only
way to verify that software works is to
run it with realistic faults. And this
is exactly what Antithesis does. You can
bring the system you work on under test
and verify that it works as it should.
Teams at Etsy and Jane Street are doing
just this. And I'm also starting to use
Antithesis to test real-world systems.
Over the season, I'll be sharing a lot
more on how it works and how it can help
verify that a system is bug-free. In the
meantime, check out
antithesis.com/pragmatic
to learn more.
Anders, welcome to the podcast.
Thank you.
It's brilliant to meet you. You've
created widely used programming
languages including the one that I I
learned first to program with Turbo
Pascal.
How did you get into programming? Well,
I was lucky enough to attend a high
school that This is back in Copenhagen
uh that offered students access to a
computer. It was one of the first high
schools in Denmark to do so.
And we're talking, you know, mid to late
'70s now. And I sort of got bitten by it
then, you know, just this idea that you
could program this machine and make it
do things you know, the wonder of
figuring out how it was put together. Of
course, it was like completely ancient
by modern standards standards. It was
like this HP 2100 with 32K of ferrite
core memory. You could literally open it
up and see the ferrite cores. I mean, it
was it was amazing, you know, paper tape
reader and
you know, and then we got a
1 MB 14-in hard drive and that was just
state-of-the-art. The bootloader was on
paper tape cuz there was no ROM in the
machine. So, so it started up and knew
nothing and so you had to type in the
instruction sequence to load the
bootloader that would then load the OS
off of the the hard drive. And as as a
kid, what did you start to program on
it? What captured your imagination?
Well, this this was a Hewlett-Packard,
so it had Fortran, which I found to be
very quirky. It had a very slow basic
uh interpreter, but then it had Algol.
Hewlett-Packard's version of Algol,
which was an interesting compiler
implementation because it didn't support
recursion.
Uh
which is kind of bizarre. You know, the
call instruction of that machine would
store the return address in the first
word of the subroutine and then just
execute and then to return you would
jump to that indirect through that word.
So, if you called yourself, you'd just
be gone forever, you know? So, and of
course, there were no debuggers or
anything to help you figure this out, so
you just had to be real careful about
which algorithms you used, but but it
was it was compiled to machine code and
it ran, you know, and it was like you
could build games, which is what we
mostly did, like Lunar Landers and what
have you kind of thing, right? So, yeah,
it was fun. Back then, things were so
simple, right? You could see all the way
to the bottom. I mean, it it there was
just no no layering and nothing. It was
you you you were right on top of the
hardware. I guess you needed to you
needed to see all the way to the bottom
as well, pretty much, right? Back then.
Well, I mean, you you it was just so
simple that you you could, right? And
that was the beauty of the of those
earlier. That was true with the
8-bit micros and even, you know, the
early PCs and whatever, right?
And then we've just added more and more
layers over time. All right, we have a
lot of layers right now, that's for
sure.
>> Mhm. And how did you go from building
games to actually building your first
ever compiler? And what was that
compiler? I started in '79 at the Danish
Technical University. At that time also,
you know, this was right when eight-bit
micros were starting to become
available. Eight-bit microprocessors,
right? Yes, exactly. And you And there
was usually these kits that you bought
that you had to solder together
yourself, and then of course they didn't
work, and then you have to figure out
why they didn't work. So, you you you
learned a lot about the hardware, too.
And I bought
a British Z80-based kit computer called
a Nascom.
And started learning assembly
programming on on that one. And then I
also met with some college buddies, and
we ended up founding a company. We had
the first
computer store in Copenhagen where you
could walk in and buy a computer, one of
these kit computers. And later
we sold Apple IIs and Vic-20s and
Commodore 64s and blah blah blah, you
know, all all of those different ones,
right? TRS-80s. So, I did a lot of
programming on those and found that
programming was really the thing that I
enjoyed. And of course, they all came
with Microsoft's ROM BASIC.
Um
and which was slow, but it allowed you
to write programs. Um but I always like
missed having a real programming
language.
Uh something like Algol or that I had
been taught, right? And then my my
buddy, the guy that I founded the
company with He was like, "Well, there's
this new thing called Pascal. You want
to check it out. And it's it's even
supposed to be simpler than Algol,"
which was which was actually true of
every language we have created. They got
increasingly simpler
as time went on. And Pascal was not that
hard to implement. And so, I got
interested in trying to do that.
Um and then wrote a little compiler
that fit into a 12K ROM.
Um that would compile a subset of
Pascal. And you could then yank out the
Microsoft ROM BASIC and stick in our ROM
instead. And then when you booted your
machine, you were in this little
environment where you could type in
Pascal programs and run them. And And
that was sort of the early precursor of
of Turbo Pascal, if you will. Many years
later, you joined
uh Borland, and I think it was in 1989,
and there you created Turbo Pascal, the
programming language, but also the IDE,
right? Well, there there's a little more
to that story. Uh
in that company that we had back in
Denmark, I ended up writing eventually a
a full implementation of Pascal for
eight eight-bit CPM-80. And then we
ended up doing a joint venture with
Borland, which was also a Danish
company. It was originally founded in
Denmark, and we
we made a royalty contract where they
would sell
our compiler
uh on a royalty. And that's how I got
involved in Borland. And we shipped that
first product in '83,
the first version of Turbo Pascal.
Um and then that took off
more than more than any of us had
expected. And eventually that ended up
being the thing that I did full-time.
Why was it called Turbo Pascal? I
understand you added things on top of
Pascal that was there. Well, I mean, it
was it was called Turbo Pascal cuz it
was fast. Back then, turbo was like this
was like it was Audi had their Quattros
and their turbos and the whatever, you
know, and turbo just meant fast, right?
And this thing was fast.
Uh and super interactive, right? And so
so Turbo Pascal it was. When Turbo
Pascal became big, was it big just
because of the compiler or also there
was an IDE a dedicated IDE for for Turbo
Pascal, right? Yes. Yes.
That was always the idea, and that that
goes back even to the predecessor of
Turbo Pascal, this idea that it's not
just a compiler. It's an experience,
right? I mean, you don't just compile
your programs. You also edit them. You
also run them. You also debug them. You
also have a runtime library. It all has
to like fit together. Do you know what I
mean?
And so Turbo Pascal was always about
building that whole cycle and try to
make it as interactive as as as basic
was as an interpreted language, right?
But giving you the performance of a
compiled language and the better, you
know, semantics and syntax of of of of a
Pascal versus basic. And so, that was
sort of the the idea from from day one,
you know.
Focus on the the whole cycle. And so,
when you were building the compiler, you
were already thinking of ways that the
IDE, for example, could make sense of or
could have helpful features for, maybe,
that the editing or debugging, for
example.
>> Oh, absolutely.
>> [laughter]
>> You know, the
the first versions of Turbo Pascal
didn't have a debugger, you know. You
you would just use writeln statements
and then uh and then then you'd just see
what happened, right? But, often if you
had some error and and it blew up, you
know, with a runtime error, we would
print out the address of the runtime
error, which is where where was the
program counter at that that that that
point. And then we had a mode in the
compiler where we would say, "Compile,
but stop at this address."
And so, the compiler was real simple. It
would just produce object code. And then
once it hit that address, it would just
say, "Well, whatever I'm syntactically
looking at right now, that must have
been around where the error was." So,
that was like how you could go to the
line where the error had occurred. Do
you know what I mean? It's it's not like
we had like line maps or debuggers or
any of that stuff. We just had the
compiler and it was just easy to make it
stop at a certain address, you know, in
the in the object output and then show
you where it was in the source code.
>> think Turbo Pascal was so popular? I I
remember back again, this was my first
programming experience. It was at
schools. It was outside of schools for
production software. And you you said
yourself that it spread like wildfire.
It was just better than all the
competition. It was faster. It was
smaller. Um it was more interactive and
it was also cheaper.
So, it was like 10 times better at a
tenth of the price of the of the
competition, right? Compilers back then
used to cost $500 and they were just
compilers and then you have to have an
editor and blah blah blah and it was
like this whole long-winded cycle of
inserting
different disks with compiler paths one
and two and what have you and and here
was this thing that just like
made it all go away and you could get it
for $49.95.
And for $49.95, I mean, heck, that was
worth it just to get the the manuals
that came with it, right? I mean, so
So, there was very little piracy because
it was so cheap.
Although,
speaking of piracy, we always had the
joke about
the the Russian site license, how we
sold one copy to Russia.
>> [laughter]
>> And then that got copied everywhere. But
after Turbo Pascal, you built Delphi,
which was an even bigger setup in many
ways that this was this was now a
integrated environment for for Windows
development. How did you evolve ideas
from Turbo Pascal and Delphi? The big
thing that happened there between Turbo
Pascal and Delphi was the advent of the
graphical user interface, right? We
switched from
running DOS in in text mode to running
Windows in in
in a GUI and that meant a new kind of
application, right? Uh that you had to
create. And at the same time,
competitively, Microsoft had created
Visual Basic, which was a very
impressive product, but still had some
of the very same flaws that we knew how
to compete with, right?
In terms of interpreted versus compiled
and extensible versus not or not
extensible versus ours that had classes
and object orientation and blah blah
blah. First, we set out to build a
Visual Basic competitor.
But then we also realized that well,
that's not really enough of an angle.
And then there was this other phenomenon
that was happening at the time which was
called client-server applications.
Um and there were a whole bunch of 4GL
application development tools for
database connected client-server apps.
And so, we set out to
build a tool that was like as
interactive and rapid application
development as Visual Basic, but with a
compiler behind it, target it also at
client-server enterprise apps. That were
And that was what Delphi sort of was
about, right? It worked out really well.
I mean, that that was the That's That
product to this day is still being used
actively by a a whole number of
programmers. I was very surprised when I
worked at Skype um right after Microsoft
bought it. I know. Yeah. Yeah. The Skype
application, you probably know this, it
was built in Delphi. It was. And in 2012
or 2013, there was a plan to rewrite it
and move it onto something else.
That rewrite, midway a year in, stopped.
So, I'm guessing that until the end of
of that Skype application, which was
decommissioned maybe a year ago.
>> It's amazing, isn't it? I mean, the
Delphi was is was and is in in in in in
some ways a wonderful way of building
Windows desktop apps. I mean, they had a
great you know, the the VCL, the Visual
Class Library that allowed you to
inherit components and install them on
the palette and make drag and drop work
for your forms designers with components
that you had built and whatever. It was
It was pretty cool. Yeah, and and we
already heard the the Microsoft link
with with Visual Basic. So, you joined
Microsoft in 1996. You worked on the J++
and then later C#, but can you take us
back to that moment in time? What was
the kind of programming environment
like? Well, the environment particularly
around the time where I joined
Microsoft, um
the mid-90s, Java had happened. Uh Well,
the browser had happened first of all,
and JavaScript. Uh But JavaScript, no
one really paid attention to JavaScript,
cuz that was just this little whatever
thingy that that was in the browser, you
know, and it was slow and it was like,
"Eh, no one uses that." Uh but then
there was this Java thing that allowed
you to create applets. Oh my god.
Applets fantastic and right on the
browser.
>> and everywhere. Yep, yep, right on the
browser and everywhere supposedly and
then and this language that was like
simple yet had object orientation and
byte codes and like like was platform
independent and I mean it was like
everyone was running around with like
with their heads cut off thinking this
was the end of languages. You know,
Java's going to flatten the the universe
and then and we're all just going to be
writing Java and Java applets and that
that's the that's it.
>> [laughter]
>> Little do you know and and and I
actually came to Microsoft ostensibly to
to be the the architect of Microsoft's
Java development tools.
And and worked on Visual J++ 6.0 was the
the version that They had Visual J++ 1.1
at the time I joined, which was
basically take Visual C++ yank out the
C++ compiler, sticking a Java compiler
and call it good.
Uh, but it wasn't interactive. It wasn't
rapid application development and
whatever and I came sort of with a whole
host of knowledge of
how to build interactive development
tools. And that's what we set out to do
with with Visual J++ 6.0.
Uh, and we also of course knew that,
"Hey, you know, I mean people are going
to be running on Windows and they're
going to want to be able to build
Windows desktop apps." And so we built a
class library that allowed you to do
that. This was the precur- WFC I think
it was called, but it was the precursor
of of WinForms, uh, you know, in in in
some ways. How did the development of
J++ go and and eventually how did it
lead to the idea of like, "Okay, let's
do something else completely completely
different?" Well, you know, development
of of J++ went went great until the big
Sun Microsoft lawsuit got in the way.
Um,
and and there was you know, and that is
like I mean and now we're talking like
business and whatever. It had nothing to
do with with with with with technical,
but it effectively meant that Visual J++
was never going to be
a product that companies would make a
bet on because they full well knew that,
you know, you you're not going to you're
not going to write your app in a in a
language that has been enjoyed by a
judge in San Jose, you know, or or
whatever. And so, we kind of realized at
that point, too, that maybe it's not a
great strategy to to
place your your development platform bet
on on technology that's licensed from a
competitor. And and that in turn, along
with the sort of dev situation at the
time, I mean, Microsoft's main
development
products at the time were
in two camps. There was Visual Basic,
rapid application development loved by
everybody, you know, cuz it was so easy
to build apps, right? But,
performance-wise, had problems,
extensibility-wise, wasn't so great. To
write new components, you had to write
them in C++ and whatever and
and then we had C++ with MFC and power
and expressiveness, but really what
people wanted was
both.
They wanted something that rolled both
of those up, right?
And then they also wanted like modern
things like garbage collection that say
Java had, for example, right? And
exception handling and a more
object-oriented, component-oriented way
of building your apps and and and all of
that was part of the genesis that led to
to .NET and to the C# language. So,
which one was first, .NET or C#
inside of of Microsoft? Well, they were
simultaneous, I would say, because we
knew we wanted to build
a runtime that
was
language independent because we knew
that we wanted to run Visual Basic on
it, and we wanted a way of running C++
on it, and we wanted the ability for
other languages
to to host themselves on this runtime.
But, we also knew that we needed to
build a language that would appeal to
both Visual Basic and C++ users and give
you sort of that golden thing in in in
the middle, right? And to be frank,
something that could compete with Java,
right? And so
so that's why we
we started out building C#.
And then when you started out building
C#, what were your design goals? You
mentioned a few things with garbage
collection or exception handling, but
how did you come up with like, "Okay,
what what will this language be?" Well,
like I said, I mean the the overarching
thing was this: power and productivity
of C++ with the ease of use of Visual
Basic
in a sense, right? But, what it also
meant was we we knew we wanted to build
an object-oriented language, we wanted
managed code or bytecode so we could
target different runtime environments,
we wanted garbage collection, um and
exception handling, but also things like
a unified object system where
and that's true in in in C#, like
anything can be assigned to an object,
and if it's a value type, we box it but
but and and it's a self-describing
object. So, reflection, you can ask an
object, "What are you?" and you can get
all of the facts about it at runtime,
and you can dynamically manipulate it in
ways that are just
don't exist in a in a in a lot of other
environments. So, we we knew we wanted
to go there with that. We wanted a
language that made
this new model of properties, methods,
and events first class, because that was
how components were built, as opposed to
just sort of functions and procedures
and and and and even objects, right? And
then we we actually also wanted to to
create a language that was standardized.
We wanted to give this language to a
standardization committee, um and try to
you know, level the playing field there.
And all of those things were sort of
like what was rolled up in in C#. You
definitely did. C# was my first
professional language where I I I worked
for that I think for about 5 years and
I've I I've seen both the tooling, the
capabilities of language and I still
think to this day in many ways that old
version of C# was ahead of some
languages today and in some ways. So,
it's very interesting to see how rich
that language was when it came out and
of course the developer love that
followed. But, can can you take us back
of what did it take to build a language
like this? Just in the more again, the
software engineers people are listening
they're used to building SaaS apps,
back-end services, you know, like like
certain projects, but we are not
familiar with with what it takes to
build a language, especially something
with such large ambitions inside
Microsoft. You knew millions developers
ideal would be using it. How did you get
to this? Did you How did you come up
with the road map? How big or large or
small team needs to work on this? I
think early on we decided that we want
to have a
team of people design this language, not
just
one. I was sort of
the guy who ran the group of designers,
but we put together a a group of six
people or so, six seven people and we
got in a room three times a week for 2
hours
and just started the design, you know,
like literally
let's start from the top. What is a We
all knew what a I mean, these were all
people who had built or worked on
programming languages before, right? And
and had seen all of the things you're
supposed to do and all the things you're
not supposed to do. And quite honestly,
language design is 90% the same and 10%
new for for pretty much every language.
Every language you build still has to
have a compiler. Compiler is still built
in a pretty much the same way. And of
course, as time marched on, people
demand more and more. You have to have
IDEs, you have to frameworks, you have
to blah blah blah blah blah, you know,
and it's all there there's So, there's a
lot of experience you want to pull in.
And and there's a lot of work that
you're doing that isn't really per se
new.
Um but but but every time around you you
try to fix the problems that you've been
exposed to. This language design group
worked together for years on end.
And it was lovely to come in to work
with a new idea and then immediately
have five or six people that you could
sit down and have a deep discussion with
without first having an hour level
setting. Do Do you know what I mean?
>> Yeah. Yeah. Um and and and and that
worked really really well because
because we could just jump right in, you
know, and and have two hours of
technical discussion. And everyone was
cognizant of okay,
if someone comes up with a new idea, now
it's our job to try to shoot it down.
What What's wrong with this idea? Do Do
you know what I mean? And if it could go
if it could stand the the test of of
that, then it was probably a decent
idea. And so so that was kind of how we
we we ran the design. And then I I wrote
the specification of the language in
parallel with our design meetings. And
then we had a group that was in parallel
implementing the compiler.
In actually implementing it in C++ or
rather
C plus minus because we didn't use all
of the C++ features, you know, in in
that compiler implementation. But it
wasn't we it wasn't until the Roslyn
project that we that we self-hosted the
C sharp compiler. And Roslyn meaning
that the compiler is in C sharp, right?
Exactly. Yes. Yes, that was the
a project that came later to
to build the compiler in itself. And
also early on, you know, this is you got
to remember back then IDEs were not
really all that fancy, you know. I mean,
we have syntax colorization. Statement
completion was kind of like well, some
IDEs were starting to dabble in it, but
it wasn't really norm. So, we built like
in a sense a classic compiler, but then
we also built this like mini language
service e thing that that sort of cut
some corners and whatever, but could do
some rudimentary statement completion
and syntax coloring. But in a sense, we
had two implementations that we had to
evolve in parallel. And over time, that
became quite a drag, right? Because as
we added generics and added other
features and link and whatever, and it
was like, "Oh my god, now now
this is like we got to go implement all
of these features twice
in the in the real compiler and in the
language service, right? And so, that
ultimately led us to
this project called Roslyn, where
we built a single compiler that really
is both
it's a compiler that can both function
as a command line compiler and as an
interactive service inside the IDE.
TypeScript is built that same way, also.
And there's a lot of learnings from from
doing it that way.
That are still not being taught in
school.
There are many useful things not being
taught in school, even when they are
useful to learn about. One of these
really useful tools that I must mention
is our seasonal sponsor, Turbo Puffer.
Turbo Puffer is a ridiculously scalable,
fast, and cheap vector and full-text
search engine built by an engineering
team that I really like. The first time
I heard about them was when I was
talking with one of Cursor's co-founders
about how their vector database could
not keep up with the number of code
bases that they were adding. This was
back in 2023. Cursor did something
seemingly risky. They took a bet on what
was a little known and relatively new
product at the time, Turbo Puffer. But
it paid off. Cursor moved their semantic
search workload over, and Turbo Puffer
was indeed able to handle Cursor's
massive, ever-increasing load.
The reason has everything to do with
smart engineering. Turbo Puffer is built
on top of object storage with smart
caching on NVMe SSDs. Cursor's active
code bases get loaded into the cache, so
searches are fast, and inactive code
bases fade into object storage. Cursor
has so many good things to say about
Turbo Puffer. They cut their semantic
search costs by 95% when they switched.
They think of Turbo Puffer engineers as
an immediate extension of their team in
Slack. And Turbo Puffer is one of the
few pieces of infrastructure that they
have not had to worry about as they
scaled. Today, Turbo Puffer indexes over
4 trillion documents for vector and
full-text search and is used by the
likes of Anthropic, Notion, Linear,
Ramp, and many others. I'm getting to
know the Turbo Puffer team and will
share more about some of the cool things
that they do behind the scenes
throughout the season. If you need
vector search or full-text search at
scale, think Turbo Puffer. Check it out
at turbopuffer.com/pragmatic.
When it comes to useful tools, I need to
also mention our season sponsor WorkOS.
One theme of today's episode with Anders
is how he has spent the time frame
thinking about developer productivity on
a scale that most of us do not. Decades,
not months or quarters. WorkOS takes the
same kind of a long-term view on
enterprise infrastructure. SSO, SCIM,
RBAC, audit logs, they've spent years
getting these right so you do not have
to spend weeks implementing them. That's
why the fastest-growing AI companies
trust WorkOS. Visit workos.com to learn
more. And with this, let's get back to
building languages with Anders.
And when you're building a a language as
as the your product was I guess the the
language itself, how did you get
feedback? Of course, you had the the you
already said the group criticized it.
Did you have an internal beta testers
cuz again for like a back-end service,
you would typically have a dogfooding,
alpha testing, beta testing, and then
you go public at some point, but this
this is not your your average software
as a service for sure. Yeah, I I mean,
luckily, we had internal clients. The
.NET Framework
very quickly
started implementing in C#. They had
sort of used a hacked-up version of C++
to to implement which was kind of odd
because I mean, it was like targeting
byte codes, but not really. And and so,
they switched to to to C#. And that
helped a lot.
Um and then we had other internal teams
using it and so we we got a bunch of
feedback that way and then we had, you
know, the cycle was not that long,
right? I mean, I think we started in
late '98 and by the PDC of 2000, uh we
had we signed up I mean, we basically
gave away beta copies, right? And and
got tons of of of of uh of users onto
it. Now C# introduced a lot of new
features that were net new, I think, to
to programming languages. LINQ is
certainly one of them, but one thing
that might have been maybe one of the
most influential uh parts that other
languages adopted as inspiration was the
async await uh setup. Looking back, what
do you think you got right with this
design and and why did it become so
copyable across languages like
JavaScript, Python, Rust, and others?
Well, a lot of languages are
are built around
cooperative multitasking in the sense
that they have an event loop that sits
and dispatches events and then, you
know, you handle the event and then you
yield back to
the event handler loop and it all runs
in a single thread cooperatively, right?
The problem with that is if you then
want to do some long-running work, how
do I stop in the middle of this piece of
long-running work and yield back to the
event loop cooperatively, right? And
then
and then when my result is ready, then I
can come back and continue executing
here. Well, in order to do that in
in an inverted architecture like that,
you have to build a state machine. And
state machines are notoriously hard for
for people to implement cuz you got to
move all of your state off of the stack
into objects. You got to remember where
and then you have this big case
statement that envelopes your entire
logic and it's it's like it's a
nightmare to to figure out, right? But
the transformation from
serially executing code into a state
machine this this this this continuation
processing style
translation is actually one that you can
do in a machine-based fashion.
You can have the compiler write the
state machine. If you introduce syntax
that allows you to indicate where you
want to yield. And that's what await is.
Await is basically I'm saying I want to
yield here. And then when and and I want
to yield this promise and then when the
promise completes I want you to come
back here and continue executing.
And then the compiler writes a state
machine around it. And it actually turns
it into this big switch statement.
You know, and moves all of the state
that survives across the await into
something that's heap allocated so it
can be brought back. And doing all of
that work is um
is something that compilers are great
at. And so that was sort of the idea
that
we have this new style of programming
where where we're using promises or the
equivalent of promises and and the
ability to yield and then we have
callbacks and but trying to write your
program in that style that's that's
also, you know, what what JavaScript
suffer from a lot, right? It's like all
this
callback style stuff. And with async
await you get sort of the illusion that
you're just writing normal sequential
code. And then the compiler does the the
the painful transformation for you. And
that turns out to be really useful. Um
now, arguably an alternative way of
doing this is to use
threads in the OS. But the problem with
threads is that they come with
pre-emptiveness and the OS has the
ability to pre-empt you at any point in
time and that's not necessarily what you
want and and and your UI now you have to
be multi-threaded in your UI and all
sorts of other problems come along with
it. Plus threads are heavyweight and
typically not well suited for
lightweight tasks like like you could do
with async functions. So there pros and
cons. Um you know, like async await
introduces this notion of function
coloring, which is unfortunate, where
you have two kinds of functions, async
functions and regular functions. And all
the red functions can call the blue
functions, but the blue functions can't
call the red functions. And then so that
means once you want, you know, a red
function, that now all everything above
it has to be red. And then so if you
want from a sync function to call
something async, well, then you got to
turn this function into an async
function and its caller has to be etc.
etc., right?
So that's unfortunate, and that's why
some environments
like Go, for example, has
has Go routines and green threads, which
are really
language emulated lightweight threads
that kind of do what I'm talking about,
but but at a much lower cost.
But you avoid the function coloring. So
there is a bunch of different things,
but but you know, but for an environment
that already exists like JavaScript or
like C# and and the Windows event loop
and and whatever, this this was the
right solution. Speaking of JavaScript,
as as C# was becoming really popular
across startups, enterprises, and so on,
it was exploding in popular games as
well. To this day, it's very popular
with games development. But JavaScript
was starting to become more popular. Can
you can you take us back to your
observations on on how how JavaScript
went from, you know, like the the
mid-90s to this script language no one
really took seriously to just exploding
in popularity? I think it was sort of a
confluence of a number of things that
happened in the early 2000s, right?
First of all, the
the JavaScript platform execution
platform matured a lot. Like Google did
their excellent work on V8, and all of a
sudden make JavaScript a fairly
performant programming language. HTML5
got ratified, and and and we were
getting to a point now where you could
actually build real UIs
in in JavaScript. And there was this
device revolution that the iPhone set
off.
And and and all of a sudden we have all
of these different form factors. It's
not just Windows PCs on the desktop
anymore. It's all sorts of diverse
devices, but
lo and behold, they all run browsers
with JavaScript in it. Lo and behold,
the real cross-platform language isn't
Java. It's JavaScript.
>> [laughter]
>> Who would have thought?
Exactly. And so the world started
opening its eyes to that and and started
building larger and larger applications
in JavaScript. And we saw that
externally, but also internally.
And one of the trigger events was when
the um
the outlook.com team
came to see the C# team and asked us
whether we
would pretty please productize this
thing called ScriptSharp. And we go,
"Well, what is what is ScriptSharp?"
It's this cross-compiler that allows you
to cross-compile C# into JavaScript such
that you can
basically treat JavaScript as an
instruction language and and run your C#
apps in a browser. And I'm like, "Well,
why would anyone want to do that?" Well,
because then you can get a grown-up
programming language with grown-up
tooling. You can use Visual Studio. You
can You can have projects. You can do
all of these wonderful things, you know,
that you can't do with JavaScript
because JavaScript is just a scripting
language with with shitty tooling. And
we were like, "Wow,
really? Well, gosh, well,
perhaps a better approach would be to
fix JavaScript."
>> [laughter]
>> I mean, surely you're not going to be
best of breed in the JavaScript
ecosystem by telling people to write in
a different programming language.
Although, plenty of people were like,
remember CoffeeScript and all of these
other like languages that targeted
JavaScript, right?
>> Yes, so there were a programming
language, right, which generated
JavaScript, but it wasn't JavaScript
itself. Yes. Yes, they were super
popular. I mean, like so many different
things did that. But JavaScript is
actually a pretty decent little
language. There are just some things
missing. You got to give credit there to
Brendan Eich. I mean, he he understood
functional programming. And Brendan
Eich, the the creator of JavaScript, and
he got functions as first-class objects
right in JavaScript, which is godsend
and and beautiful. But it doesn't have a
type system. And Yeah. we knew from
experience that you cannot build good
tooling without a type system. You can
build
decent tooling, but it's never going to
scale. It's never going to scale to
large teams cuz you can't describe your
intents
in in the code. There's no way of
formalizing any of this stuff, and
there's no way of analyzing it, and
there's no way of using it in an IDE to
give you statement completion and
refactoring and go to definition and
find all references and blah blah blah
blah. All of that stuff, right? That
germinated the idea of, "Hey, it's
we can we could create a superset of
JavaScript
that adds a type system, and then we
could just compile it away."
But then we have Now we have the
the foundation for great tooling, and
then we could build a great tooling on
top and actually
create a wonderful development
experience, right? That was sort of like
what we set out to do. When you set out
to do this, you not only set out to do
this, but you set out for some reason to
do it as open source, which took
everyone outside of Microsoft as a
surprise because old Microsoft under
Steve Ballmer was notoriously perceived
as anti-open source back then with the
Windows and and C# back in the day, of
course, I'm talking about. You know,
Microsoft were slowly waking up to the
fact that open source
was not going to go away.
And open source was where developers
wanted to be, and they were voting with
their feet. Yet,
there's a collective DNA,
you know, that has been trained to pull
you in the other direction, right? And
and and so, that battle was we were
right in the center of that. And we we
full well knew that
there was absolutely zero chance that we
would appeal to the JavaScript ecosystem
with a proprietary programming language
licensed from Microsoft. No. No one was
going to come. It had to be open source.
There was just no two ways about it,
right? But getting that off the ground
inside Microsoft, it took some
some pulling.
Um and we paid some taxes. We We did
eventually get the okay to do open
source uh because we had two technical
fellows, myself and Steve Lucco, uh who
was the the other co-inventor of of of
of TypeScript, insisting that that was
what we had to do. And so, okay. There
people weren't going to debate that. But
but of course you have to pay the tax
and be on Microsoft's open source
repository called CodePlex, where
exactly no one was. Um and and so, we
were there for the first 2 years. Um and
it kind of was crickets, you know. And
it wasn't until 2014 when we moved on to
GitHub that things really started to get
moving
um with with adoption. And also,
honestly, it it it totally changed our
workflow. You know, there's open source
and there's open development. And and
and we were technically open source in
the beginning, but it was not open
development. We would sort of lob the
source code out in this repository and
scrape the issues off of that and put it
into our internal issue tracker. And
then, you you know,
but once we switched to GitHub, the
entire
workflow
moved to open development, also. And
that I love that workflow. And that's
we've been there now for over a decade.
Uh and it's been fantastic. Uh and it's
what made the product as good as it is.
Just over a decade later, so
the language moves to GitHub in 2014 and
in November 2025
the the GitHub Octoverse report revealed
that TypeScript became the most popular
language across GitHub. Outside of the
type system, what do you think made
TypeScript this popular? And of course,
we've had other languages, Python
being the other very popular one, but
what captures developers' preferences
this well? Well, I think, you know, it
didn't just happen overnight, you know?
And if you look back at at at, you know,
all of a sudden we we surfaced as number
10, and then we climbed slowly over the
years up and and and sat next to
JavaScript, right? And of course, if you
added JavaScript and TypeScript
together, then we were already number
one. It's just which syntax were were
you using type annotations or not? And
more and more people
over time just decided to adopt that. I
mean, some
early on were using JSDoc or or or
whatever, you know, and it like these
types in comments or or that we also
supported. But gradually, I think people
just realized, "Hey, this is this is the
right way to do it." And the reason they
came, I think, is absolutely because of
the the better tooling. And I think we
were totally right there that like
adding a an erasable type system and
then
using that to enable great tooling
is really where the pro where the
programmer productivity boost is
realized. And I guess this is where we
cannot like not mention VS Code, which
shipped that great tooling
also as a free to use for for most
people, at least initially for for for
most people, which which also made a big
difference. Absolutely. Yeah, that's our
our sister project, which is written in
TypeScript. And so, they were one of our
earliest adopters, uh and that we work
pretty closely with them um to this day.
That whole interplay, that in turn This
what led to the invention of uh
of LSP, the language server protocol
that now pretty much every tool vendor
uses to enable
interactive services in the IDE. Oddly,
it isn't until this port to go now that
we're switching to LSP. We had our own
precursor of LSP because the LSP didn't
exist when we first integrated
TypeScript into into Visual Studio Code.
But there are a lot of learnings from
from that. So it's it's been
an incredibly symbiotic and and
fulfilling experience to build these two
projects in parallel in open source.
And I think it has totally changed
people's view of Microsoft in in the
developer ecosystem. Plus
developers who again are not as familiar
with compilers themselves. We of course
like I I use TypeScript and I I'm aware
that there's some compilation going.
Could you give us a brief overview of
what the types of compiler pipeline
looks like in terms of parts and and
what parts you specifically focus on
more?
Sure. It's in many ways a fairly typical
compiler and in many ways not. Pretty
much every compiler has you know, what's
known as a lexer or a scanner that takes
text and turns it into tokens.
And then typically on top of that you
have a parser that takes the tokens,
checks their sequencing, and then makes
abstract syntax trees, which is a
you know, a tree that you can navigate
that effectively is a map of of the
source code, you know, but broken into
syntactic primitives and checked that
you know, like syntactically everything
is is or grammatically that everything
is correct. So those are the first two
stages of the pipeline.
Um
Then we have
well, we have a one extra pass that we
called a binder, which is you know, once
we have the parse trees
then we bind symbol information to them
where we find all of the all of the
declarations
of variables and whatever and build
symbol tables and attach them to their
functions such that we can then later
look up names effectively. And we also
build in the binder, we build a control
flow graph, and I can talk about what
what that helps us do. And then we have
the type checker,
which is the largest part of our
pipeline. And that's the the thing that
checks semantically that your program is
correct. It's the thing that figures out
types and checks that the types relate
correctly and that you're assigning the
right thing to the right thing and then
that, you know, that you're calling
something that actually exists them then
and so forth. And then we have an an
optional stage at the end called our
emitter.
And normally
the emitter
infrastructure in a compiler is also
quite big because that's where you go
from intermediate representation to
machine code
or byte code. Now, in our case, we just
erase types, if you will. Well, we kind
of do two things in in our compiler,
actually. Early on, it was very much
about
A, erasing the types, but B, also
down-leveling your your code. So, we
would take newer ECMAScript features
that weren't yet supported by the
runtimes, for example, classes, and then
we would down-level them to constructor
functions and whatever, and so we would
rewrite the code. And that was a very
popular feature early on. Now, pretty
much every browser is evergreen, and you
know, like ECMAScript features are are
are are caught up, and and so so that's
not as important anymore. So, our
emitter is effectively, you know, a
thing that just erases type annotations
and spits out the JavaScript code that
can run unannotated and also can spit
out declaration files, which are
summaries of
your modules and and so forth. But the
those are sort of the stages.
Now, the thing that's interesting about
the compiler, though, is that it's built
in a manner that where it can function
in a highly interactive mode, which is
what the IDE uses. Normally, you know,
command-line compilers, they just run
through these stages, and, you know, the
output is just whatever gets emitted or
some error messages, right? But in an
IDE, you know, the compiler is a
service.
And what we do in that service
is
we basically take a program that is
perpetually broken because you're
typing. And yet we try to syntactically
or semantically analyze it and because
we need to know when you press dot here,
what could you what could come next?
Well, that means we need to know what is
the type of the thing you dotted on. In
order for to figure that out, we may
have to resolve stuff. We may have to
look at ASTs over here and whatever.
And all of that has to happen within 200
milliseconds or else people think the
IDE is slow.
Right? Well, what if you have
500,000 lines of code?
You can't compile all of those in 200
milliseconds. So, you got to be super
super deferred and interactive. And so
you got to do minimal amounts of work.
And that's how our compiler is built is
it tries to front load. Like for
example, like you have 500,000 lines of
code. Well, let's say in 500 files.
Well, we could build the ASTs for 499 of
the files and just sit on them. We don't
have to rebuild those because you're not
editing those files.
We just have to update the AST of the
current file you're in.
So, that goes 500 times faster, right?
Then then if we had to do all of it. And
then we don't actually have to figure
out all of the types in here either. We
can just start
where you're at and then just resolve
just enough to answer the question that
you're that you're needing an answer for
right now. And so everything is lazy and
deferred and functional and reusable
inside the compiler. And it's a very
different way of writing compilers than
than what the textbooks will
traditionally teach you. Yeah, cuz I I
guess this is now these are interactive
compilers, if you will, right? It sounds
like it's it's it's more than a compiler
or a lot more difficult problem to
solve. The same engine is there, but but
you got to build it in a
in a manner where it can be very
interactive. And that was not typically
important for compilers, you know. And
so TypeScript is a superset of
JavaScript. What are some features you
would try to add if only JavaScript
would allow it, or if you were able to
influence JavaScript's road map? What
what what what What is something that
you feel could make TypeScript a lot
better, but of course there's a
constraint there? We track the
ECMAScript committee, and and and and,
you know, new language features that get
developed in ECMAScript, we we implement
once they reach uh stage three or four
in the standardization committee. And
then then we've sort of been on that
train ever ever since the beginning. So,
there is a pipeline that supplies new
language features
in a standardized manner. We sort of see
it as our purview to define the type
system on top.
Right? So, that is, if you will, our our
playground. Now, I still have things
that I wish I could have in the language
itself. I mean, I like functional
programming. I like functional
programming languages, and and key to
them is that that everything is an
expression. There's really no
distinction between statements and
expressions. And so, one of the the
features that JavaScript lacks, in my in
in my estimate, is is the ability to
give symbolic names to temporary results
and expressions, and then reuse them.
This is the let let blah equals whatever
in some expression, that functional
programming languages, you know, like
camel and whatever, all have.
And it's nice because you could just
stay in an expression context, and you
can just dot things together, and and
blah blah blah whatever, and sort of do
this more fluent style of programming.
But then all of a sudden you need a name
for something you want to reuse, and now
you've got to pop out and declare a
variable, or turn it into state Anyway.
You know, that's one thing that I would
like to fix. There's There's something
called do expressions that may or may
not happen at some point, but it's
taking a long time. So, anyway, but I
mean, generally speaking, I think
JavaScript is a is a nice little
language. It just has some issues, you
know, and then and I think we're very
good at teasing them out with our type
checker, right? And so So, once you have
a checker that can warn you, "Hey,
you're about to do something stupid
here."
Then,
it's not so bad. The thing that makes it
interesting, I think, and and unlike
pretty much any other programming
language is the gradual typing.
This This notion that
you can have types, but you don't have
to have types. Other languages force you
to type everything, right? Um, because
they in turn use that information to
generate
machine code, uh, you know, based on
what the type is, you know, different
instructions for float versus int versus
whatever, where
in JavaScript, the types or in
TypeScript, the types are They're purely
for
the development experience and the
checking. When the program runs, they're
all gone.
Now, of course, there are still types,
but they're all dynamically computed.
But that's kind of interesting because
that means in the language, we don't
necessarily have to prove 100%
correctness. And a lot of language
features that we have, we can't 100%
prove correctness.
Like in a structural type system with
recursive types, there are just cases
that you can't analyze because the types
are infinitely recurring. The more you
try to relate two types, the deeper you
go, and you're just staring into the the
recursive abyss. Do you know what I
mean?
But you can kind of go, "Well, well,
we've proven it to four levels.
That's probably good enough. We're just
going to say it's good enough." And
then, you know, if everything else works
out, we're going to go, "Sure." That you
can't do if if you were to go generate
machine code that then would have
indeterminate behavior, right? But if
JavaScript has a runtime where
everything is well defined already.
So, if we're checking 99% instead of
100%, well, heck, that's better than the
0% that JavaScript checked, right? And
it gives you like language features that
no other languages can provide because
they can't get to 100%.
>> [laughter]
>> It's interesting how constraints lead to
innovation or even limitations can lead
to more innovation. Speaking of
innovation, one one of the biggest
innovations that is everywhere is the AI
agents, AI coding tools that us software
engineers, most software engineers are
using, increasingly using AI agents as
well. As you're developing languages on
on on a more, I guess, niche team, what
kinds of uh AI tools are you using or or
how is AI helping your language
development work? May that be TypeScript
or C#. Day-to-day I work on on
TypeScript and I can certainly talk
about how we've been
in the process of moving TypeScript to
native code for the last year and a half
or so. In the beginning of that project,
AI was nowhere near as capable as it is
now, and therefore we could not really
use much of it in the beginning. At this
point though, I'd say we're using we're
using AI fairly well. Obviously,
we're on GitHub, we use AI to code
review pull requests. That in the
beginning was not all that great, but
now it's actually getting a lot better.
Um
we use uh AI to implement issues or or
fix issues,
simple issues. And then it succeeds some
of the time.
Um in this port that we're doing, you
know, because we snapped a copy of the
source code from a year and a half ago
and then ported it.
We have a backlog of PRs that need to be
moved on to the new native compiler, and
so we're using AI to help us move those
pull requests.
Um and that's actually going fairly well
at at this point. And then
we use it for a bunch of drudgery
drudgery work like okay, here's this
feature. Please write me some tests in
the same style as these other tests,
right? And kaboom, it's like no one
likes writing tests. AI loves writing
tests and it'll just pump out more tests
and great, you know, so so we're trying
to use it to
get rid of all the toil that otherwise
we would spend our time on, right? But I
would say we're not at point where it
absolves us from understanding what
we're doing.
>> [laughter]
>> Not at all. No.
Well, plus your level at the the stack
if you will because you're building a
language. It might argue that someone
really needs to understand at least one
person. Ideally the whole team needs to
understand those fundamental parts,
right? Oh, absolutely. I mean and and
it's
language is interesting in the in the
world of AI because AI
like a lot of like this this
conversation. We wouldn't have this
conversation if it wasn't for languages
because how would AI get to determinism
without programming languages, right? I
mean AI is by design stochastic and
indeterminate. It might give you a
different answer the next time you ask
it the same question either just because
random or because there's a new model or
there's a whatever. It's non it's not
the it's there's no determinism. Yet
we can't build applications if they're
not if they have non-deterministic
behavior. I mean what would a banking
app look like if it like decided to
hallucinate or or whatever, right? So
you have to have
something that where the rubber meets
the road and where you can reason about
and and where you can replicate the
behavior every time you run the app the
same thing happens. Absolutely. I mean I
even see it in a bunch I think almost
all AI agents or tools these days when
you ask it
something to do with data, often times
it will start writing a Python program
because I think the AI designers figured
out that you at some point want to turn
some non-deterministic into a
deterministic and exactly What is
exactly the thing that we know most
efficient? You don't ask it for the
answer, ask it to write a program that
computes the answer.
And and you will know that that that
will be deterministic. Yes, exactly.
Yes. Yes.
>> It's it's very interesting. But speaking
of
languages for for AI, I had a question
that comes up, of course, because AI is
everywhere is generating a lot more
code. What is your take on either
modifying existing languages for AI
usage based on what you're seeing with
the patterns or potentially coming up
with Would it make any sense to come up
with a language that is more suited for
AI agents to use? Well, my flip and
answer there is, you know, that
the language that's most suited for AI
is the language that AI has seen the
most of in its training set, right? And
that's why you could argue AI does
really well on JavaScript and TypeScript
and Python because it's seen an awful
lot of it and there's an awful lot of
that still and then and then so and that
just reinforces itself, right? And and
you can argue, well, the reason
TypeScript and JavaScript are are
popular, well, that's mostly to do with
the browser and not so much to do with
AI, right? But it's interesting to look
at why is AI targeting TypeScript versus
just JavaScript? And there I think the
types actually help guide the AI
um to to producing better programs. And
I think our combination of
the ability to type something when
there's no context,
but also the our ability to infer it
when there is context is just the right
combination because if you were to force
AI to write a type annotation on
everything,
then it would probably get it wrong more
often
because now it has to keep track of all
these types and and it and it has to
just repeat itself over and over and
over, right? And so, types are important
where there's no context. But inference
is super important for for the dry or do
not repeat yourself principle, right?
And and and fewer tokens generally makes
AI more efficient and so so I think we
have a very nice combo there in in how
how you can just sort of type the
outermost parameter and then everything
flows
from there on in, right? Now, one one
thing that AI is already resulting in,
again, for the GitHub team share stats,
so this is also open data that AI agents
are generating a lot more code. I mean,
they're both quick to generate, they
also like to be sometimes verbose. Uh
knowing that we are already seeing a lot
more code pushed everywhere and and from
at a project level, at a at an aggregate
level, what do you think language
characteristics could become more
important in this world of of just a lot
more code often times generated by
machines. I mean, you could argue that
we we're already past peak truth on the
on the on the internet, right? And now
there's there's just more and more
garbage every every day. It gets harder
and harder to suss out the stuff that
you do want to include in the training
set in order to actually make something
more intelligent. So I think that's that
gradual I mean,
I'm sure people are working on it. I
could see that as as as becoming
problematic. Languages that are suitable
for AI I I think like I talked about
types and inference. I think both of
those are important. I think also
locality is is important. Locality?
Well, what I mean by that is like don't
have a bunch of global stuff where AI
has to grok the entire product or these
pounding glue files that are oh my god,
well, who knows where they're in scope
and and how
do I put that in the context window or
not? And then then do I burn like a
gazillion tokens on on trying to include
but
but if you have good locality where you
you clearly stating what you're
importing and whatever and and you can
analyze just a single source file and
from that extract its protocol to the
outside world without having to to know
anything deeper. Do you do you know what
I mean? I think those are important
aspects
just simply to reduce the size of the of
the of the context window and also make
it easier to summarize each module in a
program, right?
>> This is so fascinating because I
remember this was probably 15 years ago
where PHP was very much critiqued for
its globals. And early on I didn't
understand as a young developer why that
was a big deal. I was I was just hacking
on in PHP until I had the issue of
something was not working and turns out
that something imported over with a
global and suddenly you realize that
when things are defined across the code
base a global could be anywhere and
there's no way for you to to know when
someone else is doing you're now back to
the state problem which you just
talked about. Original JavaScript
suffered from this problem. There were
no modules, right? Everything was global
and anyone could just like monkey patch
anything else and
and it was impossible to know really
what what what what am I sitting on top
of here? But now with ECMAScript modules
and whatever we're we're we're moving
towards sanity and more and more the
world is written that way in the
JavaScript ecosystem and that's a good
thing and I think that will help us down
the line with with AI. AI today
it's just starting to to
become aware of you know the existence
of of of language services and agents
today like to use grep and awk and
whatever you know to to find all the
places where you reference a certain
thing but it's not semantic search,
right? And so so if you have a a common
name for this property like count or
address or or whatever, right? Well,
it's going to find a whole bunch of
properties named address, and then that
that's not going to work so well,
because now you you don't know that
you're renaming the right one, right?
But this is where language services come
in and and semantic search. And I think
that's going to increasingly become more
important with AI. And really the these
are services that are already provided
by LSP implementations.
But they may need some tweaking in order
for them to be more accessible to AI. AI
likes command-line tools, you know, and
they're not really command-line tools.
And I also wonder if if for example
performance will be interesting because
we know that these things can can run
faster, so faster feedback is will be
clearly helpful, which we're now going
back to type one of the reasons that
TypeScript was so popular is that the
200 milliseconds of getting you
feedback, right? But there are ways of,
you know, where where you can imagine,
you know, like a server keeping a
project hot and and giving your LSP
services, you know, that AI can ask
semantic questions and and whatever. And
then once AI stops asking that for 10
minutes, the server just dumps it, you
know, and and whatever. So, there there
are ways of putting this together, I
think, where we can make some progress
on on because like the ability
for AI to semantically validate the code
that it's generating as it's generating
it will increasingly become important.
What about the the software craft?
You've you've you've been in this
industry for for many decades, but it's
hard to unsee that these tools are just
coming to everyday use, similar to how
at some point graphical IDEs came before
that. I guess the higher-level languages
came.
Knowing that AI agents and AI tools will
be part of the craft, what do you think
parts of software engineer craft will
become less important and what might
become more important? In a sense, we're
all turning into project managers,
right?
And and we can have an army of junior
programmers called agents that will just
spit out reams of code,
but someone's got to have the big
picture
and review all of that. And so,
increasingly our craft is going from one
of
writing the code to one of of reviewing
the code and and building the
architecture of the code and overseeing
the work, if if you will. It's a
different kind of craft. It's a
different kind of enjoyment. I've always
liked writing the code.
You know, to me that was the fulfilling
part, seeing it work. Do you know what I
mean? And and it in in a in a way AI
robs a little bit of that, right? I
mean, because I I I am less interested
in reviewing code, but I think we could
also make the process of review of
reviewing code much more interesting
than it is today, right? I mean, today
you see a list of of diffs in
alphabetical order and and now it's up
to you to to make heads or tails of it.
I mean,
there are more pedagogical ways of
presenting that and and you could have
commentary generated by the AI that
tells you what the changes are and
whatever and then tries to guide you
along. Do you Do you know what I mean?
So, so that symbiotic relationship, I
think we we need to work on that more
and so sort of to to to keep the
enjoyment in there, but I think it's
foolish to think that AI will just
eliminate programmers and that because
ultimately that's
you know, like like vibe coding is
wonderful as long as it works. And then
the minute it it goes off track, then
you're like you have no idea what's
going on and you can't convince the AI
to fix it. And so, what do you do?
You can't absolve yourself from
understanding what's going on. That
that's not that's not programming. And
ultimately also, you know,
the responsibility for a program does
not lie with the AI. It lies with the
programmer.
You're not going to go back to the eye
and say, "Shame on you. I'm going to
fire you."
>> [laughter]
>> What does that even mean, right? I mean,
now you have nothing, you know, it's No,
you need someone to have that
that function of being responsible. And
so so that's you know, so so ultimately
AI is a tool to enable us to become more
productive, I think. But it will change
the way that we write our programs, for
sure. I mean, there's no point in
in in in sitting there and typing in
stuff that AI could type 100 times
faster, you know. Having created three
very widely used programming languages,
what have you learned about developers,
about what they care about when it comes
to programming languages and stuff that
maybe they don't care too much about or
don't even think about it, but you might
have to think a lot about? You know, I
think at the end of the day developers
care about being productive. They care
about being in the zone, where they feel
like, "Oh, yeah, this thing is just
clicking for me. It's doing just the
right thing and it's like answering me."
But it it's it's right there. It's an
extension of my fingertips, right? So,
for me as a as a language designer, I'm
never just looking at the language. It's
you're looking You got to look at the
whole picture.
The whole experience. Because really
what you're doing is you're creating an
experience. An experience that
programmers will spend the majority of
their working life in.
Which is why my programmers become so
attached to their tools, you know, and
their languages, right? I mean, it's
it's almost a religious thing for which
language you're on, which tool you're
using, and because it's it's so
ingrained in your workflow and and it so
enables you to to be in the zone, right?
So,
that I think is the
that's the key to focus on and that's
what I've tried to do with with the with
the the work that I've done over the
years. And it sounds like this is why
from the very beginning you also focus
on the IDE, the the tool where
developers spend their time in. Yeah,
you can't have one without the other.
Well, you can, but but it's just not
it's not nearly as effective. Yeah, one
question we're starting to see or it's
more of a question mark is, well, how
much are we going to be in the IDE all
day versus these new interfaces which
might be agents where you can manage
multiple things or command line which is
again the just something where we found
that agents can work asynchronously, but
I think we're still figuring out as an
industry of like what
what will come next. Yeah, I don't know
that we can see the steady state at this
point cuz it's it's it's evolving so
much, but I still believe that that
programmers are going to be relevant in
in in this equation, you know, I I I I
fundamentally believe that. What about
performance and efficiency? Early on in
your career, you just mentioned that
your first computer you've had on how
many kilobytes it had and how you you
fit your compiler into 12 kilobytes
which these days I I cannot even create
a text
a text file that's smaller than that I
or it's very hard to do, right? But it
seems in those year in the you know,
like few decades ago, writing efficient
programs was important and over time my
perception is that it's becoming less of
a focus. What is your take on that and
do you think it's kind of fine for us
developers to forget about efficiency or
we're just allowed to do that because of
we have more resources or
maybe this will change.
I think it's a case of it depends. There
are certain classes of apps for which
efficiency is absolutely key. I mean,
the the kind of program that my group
works on like compilers, tooling, and
whatever. Yeah, people do care. That's
why we're we're spending a year and a
half moving to native code. Inference in
in the cloud on the up against the line
I mean, oh my god, you know, like
financial fast trading whatever. It's
all about perf, right? I mean, at the
speed of light and like trying to trying
to move your trade faster than the other
guys. I mean, so so there are lots of
places where perf is king. But, there's
increasingly also places where where
perf doesn't really matter because, you
know,
it's so fast anyway that if it even if
it's 10 times slower, you still can't
detect a difference.
And so, it's just not worth optimizing
there anymore. It depends, I think, on
on on the kind of app you're building.
The It's a good reminder that not all
use cases are are born equal. I'm
interested, what is your personal
development setup like these days? Well,
I'm an old Windows guy. I still I still
Windows is my desktop. I have a Lenovo
P1. You know, I like I like just keeping
everything portable. So, I don't have a
big screen or whatever. I just put this
is like, you know, what, 15 16-in laptop
with a nice OLED screen and a nice
keyboard. And that's that's
what I do my coding on, you know, pretty
much exclusively. And what what tools do
you use? Oh, I use VS Code. VS Code. VS
Code all day, every day. VS Code and and
GitHub all the time. Yes. Yes. Yes. And
and for for AI coding assistants? It's
mostly the GitHub and and VS Code stuff.
So, which means, you know, I mean, well,
you can you get to choose your your your
LLM there, right? I mean, but it's that
workflow, I think, generally speaking.
It's limited how much we've been able to
use LLMs in implementing our compiler
and implementing new language features.
It's like
it just it's it's good at surface-y
stuff. But, when it comes to like
getting the big picture and how do
types and symbols and binding and
parsing and all relate and where's
what's the most efficient data structure
here and and whatever, it's, yeah, it
it's not quite to that level. I'm also
wondering if the lower you go into the
stack, may that be very high-performance
code or or very concise code where all
these things matter, maybe the
applicability starts to drop. Because
again, we know we we already see this
LLM's, they're amazing for green field
work. When you have an existing large
application, it's it's useful, don't get
me wrong, but it's not nearly as useful.
Yeah, and and we are one big brown
field. Uh
>> [laughter]
>> Uh because, you know, we already have a
huge code base, right? And it's got a
it's got to fit in there. Plus, I mean,
to be honest, I mean, there are only so
many compilers in the training sets of
of of AI where where there's a gazillion
GUI apps written in React and and
whatever, right? So, no wonder it's good
at those, right? I was interested in
reflecting a little bit on your career.
You've now been at Microsoft for for 30
years, and you've been working on
programming languages for 40. That's
even a lot to to say, but in this
industry, it's pretty common for people
to change jobs every 3 to 5 years or so.
What has kept you at a company for for
so long and also in in a similar area
for even longer? Well, there's there's
just something about developer tools
that that is just
what I love to do, you know? And and
programming languages and they're
they're
they're complex, uh algorithmically
complex problems to solve, and I I I for
some reason like that. They have fewer
dependencies on other things, so you're
you're you're building from the bottom
yourself. Do you know what I mean? You
don't have to like sit on top of someone
else's framework and and and swear at
them when they when it doesn't do what
you want it to do, right? So,
so that kind of works for me, right? But
but the thing is like doing programming
languages, you come to realize it's a
long play.
I mean, if if you look back at the the
stuff I worked on, it it it goes in
10-year cycles at least. And TypeScript
didn't really, for example, or C# for
that matter. I mean, it took it it takes
10 years to get to, you know, version
one is great, but it has all sorts of
issues, and then you got to do version
two, and then it's not until version
three that it really starts to be great.
But then now you got to convince people
to actually adopt it and
and and it it's just it's a long play.
You got to be willing to do the long
play. Um and I think like having been at
a at a company like Microsoft is is it's
it's been great because to be put in a
position where a company like Microsoft
is putting their might behind your
efforts on creating a programming
language. That's not an opportunity you
get in a lot of places, right? And that
has been fantastic. But also, you know,
the fact that Microsoft is fundamentally
a developer-focused company. And they
they always have been.
>> Yeah, that's how they started, right?
>> Developers matter. It's not It's not
advertisers who are who are who are
paying the bills. It's It's developers
and enterprises that, you know, and and
I like that like where you feel like
you're doing an honest day's work and
people are paying you for it and it's
it's good stuff, you As closing, what
what is a book that you would recommend
and why? I always recommend the same
book, which is Niklaus Wirth's Programs
plus Data Structures uh
um
equals algorithms. It's actually like
available online now. Uh it was written
in the '70s, but that was the book that
It was a revelation for me to read this
book. This is how I how I
learned about hash tables and the how to
construct a small compiler and and
whatever. And it was it was just
wonderful. It's very light on symbolism
and very rich on examples and and and I
was always an engineer, and so that book
just appealed to me. And I think it's
still in in in in a lot of ways super
relevant today. The basics have not
changed, have they? Too much. No, no,
and I know certainly and and
particularly when it when it when it
comes to programming languages, heck,
it's it's a it's a well-established
discipline, quite honestly. Yeah, it's
been around for 50-plus years. Well,
Anders, thank you so much for this
in-depth conversation. Oh, my pleasure.
This was a lot of fun.
I hope you enjoyed this rare
conversation with Anders as much as I
did. An interesting part I keep thinking
back to is how Anders said that
programming language design is a 10-year
cycle at minimum. Version one has
issues, version [music] two fixes them,
version three is finally great, and then
you have to convince people to actually
adopt [music] it. Most of us devs are
used to thinking in quarters and
sprints. This is certainly a different
time frame. I also found it surprising
to hear how small the C# language design
team was
>> [music]
>> and how lean that they worked. Six to
seven people, three meetings per week,
two hours each. All of them were people
who had built languages before and they
were criticizing each other's ideas. And
ideas that survived the criticism were
the ones considered good enough to work.
Which is a good reminder that standout
technical work more often comes from
small [music] teams than it does from
committees. Finally, I really like how
Anders said that IDEs are the language.
From Turbo Pascal in the 1990s to
TypeScript and VS Code today, Anders
says that the compiler is not the
product. The product is the whole edit,
compile, run, debug cycle. This is a
good reminder to any and all of us
building software. [music] The product
is the complete way that your customers
use the product, not just the screens or
parts that you are responsible for. If
you'd like to go deeper on Microsoft's
developer tool [music] roots and
operating systems, check out the related
Pragmatic Engineer deep dives linked in
the show notes below. If you've enjoyed
this podcast, please do subscribe on
your favorite podcast platform and
[music] on YouTube. A special thank you
if you also leave a rating on the show.
Thanks and see you in the next one.
Ask follow-up questions or revisit key timestamps.
Anders Hejlsberg, a pivotal figure in programming language development, discusses his journey from creating Turbo Pascal and Delphi to C# and TypeScript. He explains Turbo Pascal's success due to its speed and integrated development experience, and how C# emerged from the legal battles surrounding Java and the need to unify developer platforms at Microsoft. He delves into the design philosophies behind C#, emphasizing object-orientation, managed code, and a unified object system. The discussion then shifts to TypeScript's rise, highlighting the critical role of its erasable type system and open-source approach in enabling superior tooling and developer productivity, especially with VS Code. Hejlsberg also shares his insights on the impact of AI on programming, noting how it automates drudgery and shifts the developer's role towards reviewing and architectural oversight, while underscoring the importance of determinism and language features like types and locality for AI. Throughout, he emphasizes that developer productivity and the complete "experience" of programming are paramount, a lesson learned over 40 years of language design, which he describes as a "long play" requiring a decade to achieve maturity.
Videos recently processed by our community