本集简介
双语字幕
仅展示文本字幕,不包含中文音频;想边听边看,请使用 Bayt 播客 App。
别让别人告诉你这事做不了。
Don't let people tell you that it can't be done.
他们跟你说做不了,其实是因为他们自己做不了。
When they tell you it can't be done, it's because they can't do it.
这是安德斯·海尔斯伯格,TypeScript 和 C# 的创造者,我们聊了聊 TypeScript 最近通过原生重写,速度快了十倍。
This is Anders Hejlsberg, the creator of TypeScript and c sharp, and we talked about how TypeScript recently became 10 times faster through a native rewrite.
我们能不能,就是,把 JavaScript 修一修?
Couldn't we, like, fix JavaScript?
那样不是更好吗?
Wouldn't that be better?
你明白我的意思吗?
Do do you know what I mean?
你想想 Rust,它缺了什么?如果它有的话,你就会选它?
If you think about Rust, what didn't it have that if it had it, you would have picked it?
我觉得,有两点。
I mean, I think there are two things.
如果你要把钥匙交给AI,那一切就都不好说了。
If you're gonna hand AI the keys, I mean, then all bets are off.
对吧?
Right?
为什么这个观点和我在Anthropic工作的人那里看到的差别这么大?
Why is there such a big difference between this opinion and what I see from maybe people who work at Anthropic?
人们喜欢把事情推到百分之百。
People love these, like, take it all the way to a 100%.
对吧?
Right?
但到那一步我就不跟了。
And that's where I get off the bus.
这是完整的一集。
Here's the full episode.
我们这里要讨论的重点显然是TypeScript 7的原生重写。
The big thing that we're gonna talk about here is obviously TypeScript seven with the native rewrite.
看到这个,我首先想到的是,我甚至没意识到编译器最初是用JavaScript写的,因为我通常不会想到编译器会用高级动态语言来写。
And the first thing that I think of when I see this was I didn't even realize that the compiler was written in JavaScript to begin with, because I don't usually think of compilers being written you know, high level dynamic languages.
对。
Yeah.
不。
No.
那为什么TypeScript最初是用JavaScript写编译器呢?
So why was TypeScript written originally, the compiler written in JavaScript?
不。
No.
这是个好问题。
It's a good question.
说实话,如果在TypeScript项目开始之前你告诉我,安德斯,你要用JavaScript写编译器,我会说,不,不,我不会。
And honestly, if you had told me before the TypeScript project started that Anders, you're going be writing compilers in JavaScript, I'm like, no, no, I'm not.
但我的意思是,TypeScript最初的原型,也就是早期被称为Strata的项目,实际上是用C写的,因为它有点像我们IE里那个JavaScript解析器的改编版。
But I mean, original prototypes for TypeScript, the Strata project as it was called in very early days, was actually written in C because it was like an adaptation of the parser, the JavaScript parser that we had in IE and whatever.
然后我们转向了JavaScript,但写的时候还是C风格。
And then we've moved to JavaScript, but we wrote it sort of C style.
但为什么我们选择JavaScript呢?
But why did we go with JavaScript?
嗯,我是说,如果你能在你想融入的生态系统中自举,那比把自己放在生态系统之外再去瞄准那个生态系统要好得多。
Well, I mean, if you can self host in the ecosystem that you want to be a part of, then that is just dramatically better than putting yourself outside the ecosystem and trying to target that ecosystem.
你明白我的意思吗?
Do you know what I mean?
因为用TypeScript写,我们也是TypeScript的日常用户,也是我们正在构建的工具的日常用户,每当有东西不对,我们立刻就知道,每当性能有问题,我们也立刻知道,所以在早期,这真的是一个巨大的优势。
Because by writing it in TypeScript we were also daily users of TypeScript and daily users of the tooling that we were building and whenever something didn't work right we knew it immediately and whenever something didn't perform right we knew it you know and so in the early the early years it was it was a huge boon, I think.
然后,当然,JavaScript到处都能运行,对吧?
And then, of course, JavaScript runs everywhere, right?
这意味着我们的编译器自动就能在任何平台、任何地方运行,甚至能在浏览器里运行,对吧?
And that meant automatically our compiler could run on every platform anywhere, even in the browser, right?
如果当时我们选择原生代码方案,那就不可能让它在浏览器里运行了。
Had we gone with a native code solution at that time, it wouldn't have been possible to run it in a browser.
现在我们有WebAssembly或者WASM了,你知道的,但那时候还没有,对吧?
Now we have WebAssembly or WASM, you know, but that didn't exist at the time, right?
所以那是个有意义的选择,而且说实话,那时候人们也没真正意识到JavaScript已经变得多快。
So it was a meaningful choice and honestly at that time also, people didn't really realize how fast JavaScript had gotten.
我是说,它以前非常慢。
I mean, it used to be very slow.
然后谷歌在V8引擎上做了很多出色的工作,让它达到了接近原生代码的两到三倍性能,这真的非常了不起。
And then Google did all of their excellent work with V eight and got it to within two or 3x of native code, which is pretty darn impressive.
而且用JavaScript写编译器是完全可行的。
And it was full well possible to write compilers in JavaScript.
你甚至可以让它们性能很好,因为通常决定性能的是算法。
And you could even get them performant because often it's the algorithms that determine how performant you are.
不一定非得是运行环境,对吧?
It isn't necessarily the runtime environment, right?
我是说,两者都有影响,但确实如此。
I mean, it's a combo, but yeah.
TypeScript编译器有什么特别之处吗?
Is there anything unique about the TypeScript compiler?
比如说,你懂的,我一想到编译器,就会想到Clang或者那些用于C、C++这类静态语言的编译器。
Like, you know, I think of a compiler, I think of Clang or or, you know, one of those ones that is used for maybe C, C plus plus or those static languages.
用JavaScript写的TypeScript编译器,跟这些原生编译器相比,有什么独特的地方呢?
What's unique about the TypeScript compiler when it was written in JavaScript compared to these native compilers?
我觉得TypeScript编译器有几个挺独特的地方。
I think there are a couple of things that are pretty unique about TypeScript's compiler.
首先,它的目标不是机器码,而是JavaScript。
First of all, it doesn't target machine code, it targets JavaScript.
有些人管这叫转译器。
And some people call that a transpiler.
从某种意义上说,编译过程主要是去掉类型注解,把你的TypeScript变回JavaScript,对吧?
And in a sense, you know, the compilation phase is mostly about removing the type annotations and turning your TypeScript back into JavaScript, right?
在早期,编译过程的一个重要部分是把JavaScript降级,因为那时候所有运行时环境都不是常青的,有时候人们对标准实现的程度会落后好几年。
Now in the early days also an important part of the compilation process was to down level your JavaScript, meaning all of the runtime environments at the time were not evergreen and sometimes people were lagging like multiple years behind on which level of the standard was implemented.
比如,当类被标准化的时候,大多数JavaScript运行时还没有实现类。
And for example when classes got standardized most JavaScript runtimes didn't implement classes.
但事实证明,你可以降级到构造函数并转换代码,所以我们做的一部分工作就是这种降级转译代码。
But it turns out that you can down level to constructor functions and transform the code and so part of what we did was this transformation down level transpiling of the code.
但当然,类型检查才是我们做的重头戏。
But then, of course, the type checking is the big thing that we do.
而且TypeScript的类型检查器也和其他编译器里的类型检查器很不一样。
And the type checker in TypeScript is also quite unlike any other type checker in other compilers.
通常,编译器里的类型检查器是为了指导代码生成器,因为你需要知道这里处理的是浮点数还是字符串,这样才能为那个数据类型生成正确的机器指令,等等等等。
Typically, type checkers exist in compilers to guide the code generator because you want to know are we dealing with a float or a string here so we can generate the correct machine instructions for that data type, etcetera, etcetera.
但在TypeScript里不是这样。
That's not the case in TypeScript.
实际上,因为我们擦除了类型,类型对代码的运行时行为没有任何影响。
In fact, since we erased the types, the types have no impact whatsoever on the runtime behavior of the code.
它们纯粹是为了工具和开发者而存在,用来指导语句补全、重构和代码导航,这完全是另一回事。
They purely exist for for tooling sake and for the developer sake and to guide things like statement completion and refactoring and code navigation which is a whole different thing.
而且这些类型也不一定非得存在。
And also they don't necessarily have to be there.
所以TypeScript有一个渐进式类型系统。
And so TypeScript has a gradual type system.
你可以让一半的代码有类型,另一半就是些我们不检查的任意值。
You can sort of have half of your code have types and the other half is just nnies that we don't check.
现在很少有语言能做到这一点。
Now very few languages have anything like that.
所以从这个意义上说,它是一个非常不同的编译器,也是一个非常不同的语言。
So it's a very different compiler that sense, you know, and a very different language in that sense.
这实际上让这项工作变得非常吸引人,因为我们在解决以前没人解决过的问题。
That actually made it fascinating to work on because we were solving problems that no one had solved before.
我知道很多编译器,它们把高级代码拿过来,通常还会做一些优化。
I know a lot of compilers, they take the higher level code and they typically apply optimizations as well.
比如展开循环,或者去掉重复的指令,简化一些东西。
Maybe they unroll loops or they get rid of duplicate instructions, simplify things.
在TypeScript到Java的编译过程中,会有类似的优化吗?
Is anything like that happen in the TypeScript to Java compilation process?
很少。
Very little.
就像我说的,在做降级处理时,确实有一些复杂的转换。
Like I said, when we do the down leveling, there are some transformations that go on that are complex.
但这越来越不是TypeScript的重点了。实际上,很多人只用TypeScript的类型检查功能,然后用ESBuild或SWC之类的打包工具来打包应用,擦除类型,做必要的事情让代码能在浏览器里运行。所以我们并不是真的去优化你的代码在运行时的性能。
But it is less and less the thing that's important about TypeScript and in fact a lot of people use TypeScript only for the type checker and then they use some bundler like ESBuild or SWC or whatever to package their app, erase the types and do whatever needs to be done in order to make it runnable in the browser and so we're not really there to optimize your code for runtime.
我们的目的是让你作为开发者更高效,或者让AI作为开发者更高效。
We're there to make you more productive as a developer or make AI more productive as a developer.
那么,对于这个原本完全用JavaScript写的编译器,你进行原生重写,是想解决什么问题?为什么最终决定用原生代码重写呢?
So with the native rewrite of this originally fully JavaScript compiler, What was the problem you were trying to solve with the rewrite and why did you end up rewriting it in native code?
嗯,我们想解决的问题其实很简单,就是性能和可扩展性。
Well, I mean the problem we were trying to solve is real simple performance and scalability.
JavaScript从来就不是为编译器这种计算密集型工作负载而优化的,对吧?
JavaScript was never really optimized for compute intensive workloads like compilers, right?
JavaScript 主要是用来创建在浏览器里运行的界面,最初可能只打算写个一百行左右的代码,但现在当然已经远远不止了。
JavaScript is more about creating UI that runs in a browser, was originally intended for just like maybe a 100 lines of code, but now of course it's gotten to be a lot more.
但它并不是为像我们这种工作负载而优化的。
But it's not a place that you would optimize for the kind of workload that we are.
所以,在 JavaScript 里,首先,跟原生代码相比,性能上要付出两到三倍的代价。
So in JavaScript, first of all, you pay a two to 3x perf penalty compared to native code.
我是说,这取决于具体的工作负载,但如果是做计算的话,大概就是这个水平。
I mean it depends on the workload, know, but that's but if you're doing compute that's about where it's at.
其次,在 JavaScript 里,对并发使用有很多限制。
And then secondly in JavaScript there are a lot of restrictions around use of concurrency.
实际上,JavaScript 从一开始就被设计成单线程语言,这就是为什么我们有回调、异步这些机制,因为你没法直接创建线程。
JavaScript was always engineered in fact to be a single threaded language that's why we have callbacks and async and whatever it's because you can't spin up threads.
这其实是件好事,主要是因为在一个有可变数据的语言里,并发处理非常困难,因为可能会出现竞争条件、死锁等等这些麻烦事。
And that's a good thing mostly because concurrency in a language with mutable data is very, very hard because you can have races and deadlocks and all of this good stuff.
这就是为什么函数式编程语言在处理并发时更容易,因为所有数据都是不可变的,这样推理起来就简单多了。
That's why functional programming languages are easier with concurrency because all the data is immutable and it's much easier to reason about.
所以JavaScript除了Web Worker之外,不提供并发访问,但Web Worker之间不能共享数据,只能通过远程传递。
So JavaScript doesn't give you access to concurrency other than web workers and but web workers can't share data between each other other than by remoting it.
所以你可以让一个Web Worker计算某些东西,但如果它想把它交给另一个Web Worker,它必须把它转换成JSON,不能直接传递对象。
So you can you can have one web worker compute some something, but if it wants to give it to some other web worker, it has to turn it into JSON or it can't just hand it objects.
这意味着你不能让一个Worker计算某个数据结构,然后让其他人使用它。
And that means you can't have one worker compute some data structure and then have someone else use it.
换句话说,你不能实现共享内存的并发。
In other words, you can't have shared memory concurrency.
而这正是我们想要的,以便获得我们因为没利用多核CPU而浪费的性能,现在每个人不都有多核CPU吗?
And really, that's what we wanted in order to gain all of the perf that we were leaving on the table by not utilizing multi core CPUs that everyone has today, right?
因为摩尔定律不再给我们更快的CPU,而是给我们更多的CPU。
Because Moore's Law has stopped giving us faster CPUs, it's giving us more CPUs.
我们必须找到方法在计算密集型工作负载中使用它们,否则我们就是在浪费资源。
And we got to like find ways to use them in our in our compute intensive workloads or else we're leaving money on the table.
所以我们其实在很多方面都在浪费资源,对吧?
And so we were leaving money on the table in multiple ways, right?
所以原生代码,这就是为什么我们寻找一种能让我们摆脱这两个困境的语言。
And so native code and that was why we we looked for a language that would get us out of both of those binds.
它必须是原生的,而且必须支持共享内存并发。
It had to be native and it had to have access to shared memory concurrency.
我看到你选择了Go作为语言。
I saw for the language choice you went with Go.
当我想到所有系统级语言时,那些热门的选择可能是Rust或Zig,你为什么选择Go来做原生重写呢?
And when I think of all the systems languages, the ones that are often hot or maybe, you know, Rust or Zig, why did you choose Go for the native rewrite?
我觉得决策过程其实挺有条理的。
I think the decision process was actually pretty structured.
首先,我们决定不做重写。
You know, the first decision we made was we're not going to rewrite.
我们做移植。
We're going to port.
因为只有通过移植,我们才能保留现有编译器的语义、算法和精确行为,而每个人都依赖这些来保持向后兼容。
Because only by porting can we preserve the semantics and the algorithms and the exact behavior of our existing compiler which everyone depends on for backwards compatibility.
我们本可以推倒重来,完全从零开始,但那样的话,我们最终得到的语言会不一样,因为它会在某些情况下给出不同的错误提示,或者在面对多种可能性需要做出选择时表现不同,诸如此类。
Now we could have cleaned the slate and started completely from scratch, but we would have come up with a different language in the sense that it would give you different errors or behave differently in certain situations where it has to make choices between multiple possibilities and and what have you.
对吧?
Right?
所以我们想的是移植。
So we wanted to port.
这意味着我们的代码基于某些假设。
And that meant our code makes certain assumptions.
比如,代码假设有垃圾回收机制。
Like, code, for example, assumes the existence of garbage collection.
回收机制。
Collection.
它还假设函数是一等公民。
It assumes the existence of first class treatment of functions.
你知道,函数里可以有函数,可以捕获外部状态,等等。
You know, you can have functions within functions and you can close over out of state and so forth.
在我们评估了所有这些语言之后,Go是最符合条件的那一个。
And as we evaluated all of these, Go was the one that checked the most boxes.
其实,它在所有主流平台上都能生成非常成熟稳定的原生代码。
You know, it gives us very robust and mature native code generation on all major platforms.
它有垃圾回收机制。
It has garbage collection.
而且在共享内存并发方面支持得也很好。
And it has excellent access to shared memory concurrency.
这些正是我们最看重的几个关键点。
And those were like the high order bits that we wanted to check.
而其他语言总有一些方面会违背我们的这些目标。
And every other language had something that kind of worked against those objectives.
所以对这样的工作负载来说,Go 对我们而言是合适的的。
So for this particular workload, Go was the right choice for us.
结果也证明它确实很好用。
And it's worked out well.
如果考虑Rust的话,它缺什么?如果它有的话,你就会选它?
If you think about Rust, what didn't it have that if it had it, you would have picked it?
我觉得有两方面。
I mean, I think there are two things.
它没有垃圾回收。
It doesn't have garbage collection.
内存管理是手动的,你知道。
It's done manually, you know.
或者说通过借用检查器来管理,但借用检查器不允许循环数据结构。
Well, or it's done through the borrow checker, But the borrow checker doesn't allow circular data structures.
而我们的编译器里全是循环数据结构。
And our compiler is chock full of circular data structures.
我们有带父指针的树。
We have trees with parent pointers.
我们有递归的类型。
We have types that are recursive.
我们还有互相引用的符号。
We have symbols that refer.
就是说,到处都是这种情况。
I mean, it's everywhere.
而且就像我说的,如果我们选择重写,可能能解决所有这些问题,但那就不只是移植代码了。
And like I said, if we had chosen to rewrite we could have probably solved all of that but it wouldn't have been just porting the code.
那还得解决一大堆因为走那条路而带来的新问题。
It would also have been like solving a whole bunch of new problems that we had bought ourselves by going that route.
我们试过了。
We tried.
但就是行不通。
And it just wasn't feasible.
所以我们当时只是想尽量少干活,尽快拿到回报。说实话,Rust在生成代码的质量或者并发方面的优势,也不比Go强到哪去。
And so we were just trying to optimize for doing as little work as possible to get us to the payout, which is which and honestly, Rust is no better when it comes to, like, the quality of the generated code or the or the the concurrency gains that we could have gotten out of it.
Go就挺好的。
Go is just as it's great.
我的意思是,所以我们通过那条路,用更少的功夫得到了所有好处。
I mean, so so we got we got all the bennies with for less work by by going that route.
我知道有些语言,当你说它们是垃圾回收的,语言本身有某种机制在做垃圾回收,但也有独立的库可以提供垃圾回收。
I know some languages there, when you say they're garbage collected, they there's something in the the language itself that is doing garbage collection, but there's also independent libraries that can provide garbage collection.
对吧?
Right?
有,但通常伴随着一堆限制,而且不一定有我们想要的安全保证。
There is, but it it but it comes often with a whole bunch of restrictions, and and and it doesn't come necessarily with the safety guarantees that we were looking for.
我的意思是,像Go是类型安全和内存安全的,意思是你不能随便有野指针之类的,而Rust你可以用引用计数或者各种不同的策略,但总有一点不安全的地方,你必须这样做才能让一切正常工作。
I mean, like, Go is type safe and memory safe, meaning that you don't get to just, like, have stray pointers or or whatever where Rust, you can do ref counting or you can do all sorts of different strategies, but there's always like that little bit of unsafe where you have to like do this in order to make it all work.
你知道,如果垃圾回收是语言内置的,那真的是一个独立的问题,你不需要做任何特别的事情,当然,你不能持有不再需要的数据,但引用计数也一样。
You know, where if garbage collection is engineered into the language, it really is a separate concern that is you you you don't you don't have to do anything special in I mean, of course, you you have to not hold on to data that you no longer need and whatever, but that's true of ref counting as well.
但它是语言固有的。
But it is inherent the language.
当你把它从JavaScript移植到Go时,我很好奇在这个过程中用了多少大语言模型,因为我知道有些大型项目正在重写整个代码库。
When you ported it from JavaScript to Go, I'm curious how much LLMs were used in that process because I know famously there's some major projects that have been doing rewrites of their entire code base.
我知道有个叫 Bun 的 JavaScript 项目,把整个代码库从 Zig 重写成了 Rust,看起来是个挺实用的策略。我挺好奇你们在这个过程中有没有用到类似的方法。
I know there's this JavaScript project called Bun that rewrote everything from Zig into Rust, so seems like a pretty useful tactic and I'm curious if you leverage that in this process.
用得不多,不过这也跟时间有关。
Not a whole lot, but it also has to do with timing.
我们两年前就开始这个项目了,那时候的 LLM 可没现在这么厉害。
We started this project two years ago, and two years ago LLMs were nowhere near as good as they are now.
你看,技术发展得有多快吧?
I mean, that's how crazy fast it's all moved, right?
不过我们确实用了一些工具来辅助移植工作。
So what we did though is we certainly had a bunch of tools that aided us in the port.
我觉得像扫描器和打包器这些原型,都是我们手动写的。
I'd say the prototypes we wrote, the scanner and the parcel we wrote manually.
做到那一步的时候,我们自己都觉得挺惊讶的,哇,真的能拿到十倍的收益。
And at that point, we could convince ourselves, wow, we can actually get 10x out of this.
那剩下的代码库该怎么办呢?
Now what do we do with the rest of this code base?
我们做的是写了一个工具,把TypeScript语法转换成Go。
And what we did was we wrote a tool that syntactically translates TypeScript into Go.
生成的Go代码虽然没有语法错误,但也不能编译,因为里面充满了像TypeScript那样的类型用法,这在Go里是不存在的。
This Go that comes out of it, it has no syntax errors in it, but it doesn't compile either because it's full of, you know, like, it uses types as if they were TypeScript, which they're not in Go.
所以所有这些都需要重构。
And so all of that had to be refactored.
我们不得不重做所有的数据结构之类的,但最终得到了相同的代码库。
We had to redo all the data structures or whatever, but we got the same code base out of it.
然后我们可以在这个基础上继续打磨,偶尔在局部使用它来帮助完成转换。
And then we could sort of bang on that and then in a more localized fashion maybe use occasionally to help us do the transformation.
所以这个过程是手动、自动和一点AI的结合。
So it was sort of manual and automated and a little bit of AI.
如果今天重新开始这个项目,我们会采取不同的做法吗?
Now, if we were to start the project today, would we do it differently?
可能会。
Possibly.
不过我得说,如果我们直接让AI去处理旧编译器里那大概五十万行代码,或者是在五十万到一百万行之间吧,然后让它全部翻译出来。
Although I will say if we just let AI loose on know what is it like half a million lines of code that we have in the old compiler or somewhere between half a billion and a million right and asked it to translate it all.
嗯,我不确定那样就能省去我们之后逐行仔细检查它输出的代码,以确保没有幻觉,对吧?
Well, I don't know that that would absolve us from then having to go in and carefully examining every line that came out of it to make sure that there were no hallucinations, right?
除非你有百分之百完美的测试覆盖率,否则你可能还是得去检查所有那些代码。
Unless you have 100% perfect test coverage, you probably still got to go check all of that.
现在,我觉得更好的方法,说实话,是让AI写一个程序来帮你从TypeScript翻译到Go。
Now, I think a better approach, quite honestly, would be Enlist AI to write a program that helps you translate from TypeScript to Go.
因为那样的话,你可以把随机性放在那个程序里,然后每次运行程序时都能得到确定性的行为,这意味着每次运行都会得到相同的转换结果。
Because at that point, you can park the stochasticness in that program, and then you can get deterministic behavior whenever you run the program, which means you get the same transformation every time you run it.
这总是人们忘记的关于AI的事情。
That's always the thing about AI that people forget.
它不是确定性的,所以你不能真正相信它会两次做同样的事情。
It's not deterministic, So you can't really trust that it's going to do the same thing twice.
所以我们可能会那样做,但当时AI还没有准备好做这件事。
So we might have done it that way, but AI was not ready to do it at the time.
但这并不意味着我们不用 AI。
Now that doesn't mean that we don't use AI.
我是说,后来我们在编译器相关的内部流程中大量使用了 AI,大家不都是这样做的吗?
I mean, now down the line we use AI a lot in internal processes around the compiler, as everyone does, right?
比如用它来帮忙写测试、处理拉取请求之类的。
Like help it to write tests and to move pull requests and what have you.
每次提交问题报告后,我们第一步就是让 Copilot 介入,看看它能不能帮我们修好,对吧?
Whenever an issue is logged, first thing we do is put Copilot on and see if it can fix it for us, right?
我的意思是,对。
I mean, so yeah.
在这种方法里,你用大语言模型来生成工具,然后工具本身是确定性的,但你仍然需要验证那个东西。
In that approach where you use the LM to generate tooling and then the tooling's deterministic, but you'd still have to validate that thing.
是的,但这样你需要验证的范围就小多了,对吧?
Yes, but that's a lot smaller surface area that you have to validate, right?
说实话,我甚至看到过朋友之间也有类似的情况,我们一起去旅行时,就有过相关的记录。
And honestly, I've seen that even with friends, we did some trip together and there was some accounting of that.
他付了酒店的钱,我们付了别的,然后我们得把账算清楚,对吧?
Well, he paid for the hotel rooms and we paid for this and whatever and we needed to like sort it all out, right?
所以就是,好,把所有费用都列出来,每个人出了多少也列出来,然后让AI帮我们算,对吧?
And so so okay, well here's what all the costs were and here are the pieces and I have AI fix it for us, right?
或者让它说清楚谁该给谁多少钱。
Or like tell who owes who what.
结果它特别笃定地给了一个错误的答案,对吧?
And it very authoritatively came up with the wrong answer, right?
因为它把有些结算的项目给忘了,对吧?
Because it just forgot like about some of the settlements, right?
但如果我们是让它做一个电子表格,那其实就是一个程序,对吧?
And but if we had asked it to write a spreadsheet, which is really that's just a program, right?
那结果就会是对的,因为它非常擅长写程序。
Then we would have gotten the right answer because it's very good at writing programs.
所以有时候你不去让AI直接给答案,反而挺有意思的。
So it's kind of funny how sometimes you don't ask AI for the answer.
你应该让它写一个能算出答案的程序。
You ask it for a program that computes the answer.
如果选择移植而不是完全重写,你放弃了哪些潜在的好处?
What are the potential benefits that you left on the table by doing a port instead of a full rewrite?
说实话,我觉得没什么好处。
To be honest, I don't think there are any.
而且我们也不会考虑进行完全重写。
And I don't think we would consider a rewrite.
我们对这个代码库的运行效果挺满意的。
We were quite happy with the way this code base works.
我觉得目前我们并没有在浪费任何赚钱的机会。
And we certainly I don't think we're leaving any money on the table currently.
就像我之前说的,重写代码对生态系统来说往往很伤身,因为它会牺牲兼容性。
And as I said earlier, rewrites are toxic often for ecosystems because they sacrifice compatibility.
因为一旦开始重写,你就再也回不到原来的样子了,对吧?
Because you never rewrite and you get you never get back to exactly what you had before, right?
可是为了把东西做得更好看或者更漂亮,我们就会改这改那、改来改去的,对吧?
Oh, but in the name of making it better or prettier or whatever we change this and that and this and that and the other, right?
结果就是所有用户都得跟着受罪,对吧?
And then, well, all the users get to suffer through that, right?
所以如果你想让生态保持和谐,向后兼容就超级重要。
So backwards compatibility is super important if you want to keep your ecosystem happy.
我们也确实希望做到这一点。
And we do want that.
在准备这次面试的过程中,我一直在查阅关于 JavaScript 的资料,发现这门语言的语义确实挺奇怪的。
In studying for this interview, I just keep reading about JavaScript and the strange semantics of the language.
我觉得在我的职业生涯里,大家通常对 JavaScript 都不太满意或者不太喜欢它,原因各种各样。
I think throughout my career too, people have typically not been super satisfied or happy with JavaScript for some reason or the other.
所以我的问题是,既然这样,为什么它还能这么流行呢?
And my question is, why is it so popular despite that?
首先,我觉得 JavaScript 并没有有些人说的那么糟糕。
So first of all, I don't think JavaScript is as bad of a language as some people make it out to be.
我得说,在九十年代中期,布伦丹·艾奇只有大约三到四周的时间来创造这门语言,他其实做了很多正确的事情。
I will say in like the three, about three, four weeks that Brendan Eich had to create this language back in the mid-90s, he did a lot of things right.
而且谢天谢地,他受过函数式编程的教育,把一等函数做得很好,你可以有函数嵌套函数,内部函数可以访问外部函数的状态,还可以把函数作为一等值传递。
And thank God that he had been educated on functional programming and got first class functions done right, where you can have functions within functions and the inner functions can access the outer function state, and you can pass functions around as first class values.
这非常强大,JavaScript在这点上做得确实很对。
That is super powerful and JavaScript actually got that very right.
当然,这门语言也有一些怪癖,比如所有那些自动转换,还有双等号和三等号之间那些奇怪的区别,简直让人抓狂,对吧?
Now there's some quirks in the language too, like all of the automatic conversions and all of the bizarre differences between double equals and triple equals are just like drives everyone mad, right?
但这正是类型检查器乐于做的事情。
But that's exactly what type checkers are happy to do.
它们能找出所有细微的差别,因为它们理解语言的深层语义,而这些东西没人能记住,对吧?
They can like they can ferret out all the little differences because they understand all the deep semantics of the language that no one seems to be able to keep in their mind, right?
所以,我认为这也是TypeScript变得如此受欢迎的部分原因,对吧?
So and I think that's part of why TypeScript has become so popular, right?
它确实能把JavaScript最好的部分发挥出来,把糟糕的部分留在后面。
It's like it can actually like truly bring out the best parts of JavaScript and leave the bad stuff behind.
当然,你不能不承认,JavaScript 的特点就是它是跨平台的,就连 Java 当初设计的时候也是想成为跨平台应用的开发方式。
And of course you can't like like the thing about JavaScript is it is the cross platform language like even Java that was engineered and intended to be the way to write cross platform applications.
但 Java 其实并没有真正做到跨平台。
It's not really cross platform.
它不能在浏览器里运行,你知道的。
It doesn't run-in the browser, you know.
我的意思是,它并不是到处都能运行,对吧?
I mean it doesn't it doesn't run everywhere, right?
而 JavaScript 到处都能运行。
JavaScript runs everywhere.
所以有很多理由让你喜欢 JavaScript。
So there are a lot of there are a lot of reasons why you should like JavaScript.
有了 TypeScript,我觉得我们算是把那些不好的地方都收起来放一边了。
And with TypeScript, I think we've managed to sort of capture all the badness and park it.
我看到有些项目,不知道你熟不熟悉 Dart 或者 CoffeeScript,它们好像是想替代 JavaScript 或者改进它,但现在都不流行了,所以我很好奇发生了什么。
I saw there were some projects, I don't know if you're familiar with Dart or CoffeeScript, and it seems like these were some effort to replace JavaScript or improve it, but they're not popular today, so I'm curious what happened.
我是说,CoffeeScript 基本上就是 JavaScript 换了一种语法。
Mean, think CoffeeScript was mostly it's a different syntax for JavaScript.
所以它并没有真正改变语义,也没有提供额外的工具之类的。
So it doesn't really change the semantics and it didn't provide any additional tooling and whatever.
Dart 从某种意义上说也是为了修复 JavaScript。
Dart was also in a sense about fixing JavaScript.
对吧?
Right?
但如果你能直接修复它,而不是想用别的东西去替代它,我觉得这才是对整个生态更大的帮助,对吧?
But if you can fix something by fixing it instead of trying to replace it with something else, then you're doing the ecosystem a much bigger favor, I think, right?
这就是我们做 TypeScript 想做的事。
And that's what we set out to do with TypeScript.
我们不是要改变 JavaScript。
We weren't trying to change JavaScript.
我们是想改进 JavaScript。
We were trying to improve JavaScript.
我觉得这就是我们最终成功的原因。
And I think that's ultimately why we succeeded.
我的意思是,在这个新时代,AI 重写代码库变得非常可行,我想人们会开始转向他们更喜欢的语言,而不是那些现有的主流语言。
I mean, in this new age where it's very feasible that maybe AI could rewrite code bases, I imagine people will start to go towards desired languages rather than the ones that are the incumbent languages.
我很好奇,你觉得 JavaScript 将来会不会用得越来越少?
And I'm curious if you think that JavaScript might become less used in the future.
我倒不这么认为。
See, I don't think so.
我观察到的是,AI 最擅长的是它在训练数据中见得最多的语言。
What I've observed is that AI is best at the languages it's seen the most of in its training set.
对吧?
Right?
AI 是在全世界所有代码上训练的,所以有大量的 JavaScript、大量的 TypeScript、大量的 Python。
And AI gets trained on all the code that exists in the world, Which means there's an awful lot of JavaScript, an awful lot of TypeScript, an awful lot of Python.
因此,AI 很擅长 JavaScript、TypeScript 和 Python。
And therefore, AI is good at JavaScript and TypeScript and Python.
而且,它对我最喜欢的那门我自己刚发明的小语言就没那么擅长了。
And it is less good at my favorite little language that I just invented.
事实上,训练数据里根本没有这种语言。
In fact, there's none of it in the training set.
也就是说,你必须在提示词里先花掉天知道多少token来教AI这门语言,然后才能问它关于这门语言的问题。
Which means you have to sacrifice God knows how many tokens in the prompt to teach AI the language before you can even ask it a question about the language.
你懂我的意思吗?
Do know what I mean?
所以从这个角度看,我觉得现有的主流语言反而会因为AI而更加繁荣。
So in that sense, I think incumbent languages are actually, if anything, going to flourish because of AI.
我们现在在TypeScript上也能看到类似的情况,对吧?
And we're sort of seeing that right now with TypeScript too, right?
TypeScript的采用曲线出现了一个明显的拐点,正好和AI的出现时间吻合。
There's a noticeable knee in the curve of TypeScript adoption that coincides with the advent of AI.
我确实觉得,现有的主流语言反而越来越强了。
I do think the incumbent languages are actually, if anything, getting stronger.
所有JavaScript中有多少是用TypeScript写的?
What percent of all JavaScript is written in TypeScript?
嗯,去年TypeScript成了GitHub上使用最多的语言。
Well, so in the last year TypeScript became the number one used language on GitHub.
比JavaScript还多。
There's more than JavaScript.
所以GitHub上至少超过50%是用TypeScript写的。
So more than 50% on GitHub at least is written in TypeScript.
所以我们实际上比我们想要改进的语言还要大了。
So we're actually like larger now than the language that we set out to improve.
哇。
Wow.
而且比Python还大。
And larger than Python.
如果你要
If you were to
如果按这个趋势发展下去,你觉得最终TypeScript会不会成为默认,几乎所有JavaScript都会加上类型?
just draw that out in the future, do you think that eventually TypeScript would become the default and almost 100 of all JavaScript would be typed?
其实吧,现在都是让AI来写代码,我敢说很难找到哪个工具还在写纯JavaScript。
Well, I mean, you're having AI write it, I almost challenge you to find a tool that writes JavaScript.
它们都写TypeScript,因为类型标注能帮AI写出更好的代码,减少错误,而且我们还能在运行前静态验证代码。
They all write TypeScript because it helps AI write better code because the type annotations guide the LLM towards writing towards making fewer mistakes and the ability for us to statically validate the code before you run it.
这就是区别所在。
I mean, that's the distinction.
对吧?
Right?
验证JavaScript的唯一方法就是运行它,这意味着你得搭一个运行环境,而AI可能做不到,因为AI在沙箱里运行,对吧?
The only way you can validate JavaScript is by running it, Which means you have to set up a runtime environment which might not be possible for AI to do because AI lives in a sandbox, right?
但AI可以通过工具和编译器检查刚生成的代码,然后被告知:你犯了个错误。
But AI can run through tools, the compiler, and check the code that it just generated and be told, oh, you made a mistake.
那好,我可以在告诉任何人之前先把它修好,对吧?
Oh, well, let me fix it then before I even tell anyone that I made the mistake, right?
了解了这个用原生语言重写后性能提升十倍的情况,我就在想,为什么还有人会在后端用 JavaScript 呢。
After learning about this 10x improvement and performance from rewriting in native, makes me wonder why anyone would use JavaScript on the back end.
为什么不干脆在后端一直用原生语言呢?
Why not just always use native languages on the back end?
这得看你的具体需求了。
Well, depends on your problem.
因为这里有个被忽略的关键点:你到底要在后端写什么样的东西?
Think because the thing that that overlooks is what kind of thing am I going to write on the back end?
你知道的,现在有很多非常优秀的 Web 服务器框架,比如那些用 TypeScript 或者 JavaScript 写的,对吧?
You know, like there are an awful lot of very, very good web server frameworks, for example, that use TypeScript or JavaScript, right?
所以,如果你的生态里有现成的框架能帮你更快解决问题,那就比你自己从头写要快得多,毕竟你的原生语言可能本来就不是为了针对这个特定社区而设计的。
So if there are like frameworks in your ecosystem that get you to a solution quicker than if you had to write that because your native language wasn't really intended to target that particular community.
所以我觉得这很大程度上取决于你的问题跟哪个领域更相关。
So I think it very much depends on your what your problem is affinitized with.
而且很多时候,代码的性能并不是瓶颈所在。
And often perf of your code isn't the bottleneck.
你看,就拿Python来说吧。
I mean like look at Python.
对吧?
I mean right?
基本上全世界的大语言模型训练都用它来写脚本。
It's used to basically script and all of the LLM training in the world.
对吧?
Right?
虽然其中很多代码显然对时间要求极高。
I mean which clearly a lot of that code is ultra time critical.
但那些核心代码是用原生语言写的。
But that's written in native code.
对吧?
Right?
而Python只是用来做编排的语言。
And then you use Python as the orchestration language.
而且从某种意义上说,在Web服务器里,TypeScript就像是一个协调者,负责和数据库打交道,做这做那,而最终决定这类应用性能的,并不一定是那个内部for循环是不是以原生代码运行的——其实因为JIT,它本来就是原生代码,对吧?
And in a sense in a web server, you know, like TypeScript is just an orchestrator, you know, of talking to a database and doing this and that and the things that the things that that ultimately control the performance of applications like that aren't necessarily whether that inner for loop is running as as as native code or not, which actually it is because of the JIT anyway, right?
我的意思是,先测量,再决定,对吧?
I mean, measure, measure first and then make decisions, right?
因为一旦你开始测量,总会发现意想不到的情况。
Because you always get surprised when you measure.
你提到它快了多少,我立刻想到的一个问题是:为什么之前没早点做呢?
When you talk about how much faster it was too, one of my immediate thoughts is why wasn't it done sooner?
你知道,我们刚开始做TypeScript的时候,我没想到人们会用它来写现在这么大的项目,对吧?
You know at the time we started TypeScript, I don't know that we had ever envisioned that people would be writing projects that are the size of the projects that people are now writing in TypeScript, right?
比如Visual Studio Code,大概有230万行代码。
Like Visual Studio Code is like 2,300,000 lines of code.
我们内部有些项目甚至超过1000万行代码,这简直太疯狂了。
I mean we have in house projects that are over 10,000,000 lines of code which is insanity.
当时我们可能会想,好吧,没人会写那么大的项目。
We would have just at the time gone, well, no one's ever going to do that.
但那已经是十年前的事了,或者说十多年前。
But that was a decade ago, or more than a decade ago.
我们2012年启动TypeScript项目,当时的世界完全是另一副样子。
We started in 2012 with the TypeScript project, and the world looked very different.
所以慢慢地,大家开始写越来越大、越来越大的项目,对吧?
And so gradually, people have started writing larger and larger and larger projects, right?
与此同时,我们的编译器也变得越来越聪明。
And at the same time, our compiler has gotten smarter and smarter.
我们加了一堆很酷的特性,比如联合类型、可辨识联合、控制流分析,等等等等。
We've added all sorts of cool features like union types and discriminated unions and control flow analysis and blah blah blah.
这些都让我们的类型检查变得更好,但每加一个新特性,它也会变慢一点,对吧?
And all these things make our type checking even better but it also makes it go a little slower every time we add a new feature, right?
实际上,比如TypeScript 6的运行速度大概只有TypeScript 1.5的一半。
In fact, our TypeScript six runs only about 50% of the speed of TypeScript 1.5, for example.
但TypeScript 1.5当时做的事情也确实少得多。
But TypeScript 1.5 also did a whole lot less.
所以项目越来越大,编译器做的事情也越来越多,这些都影响了你的实际产出。
So projects have gotten bigger and the compiler does more, all of which detract from your effective output.
而且就像我提到的,摩尔定律不幸地不再带来更快的CPU,JavaScript又让你没法充分利用多核,而且我们当时可能也没法预见这一切。
And as I mentioned, Moore's Law also unfortunately stopped delivering faster CPUs and JavaScript keeps you from taking advantage of the additional cores and it's not clear that we could have foreseen all of that.
对吧?
Right?
但事情就是这样发展的。
But but but it's just the way it panned out.
对。
Right?
OpenAI、Anthropic、Cursor和Vercel都在用这个产品来提升他们的效率。
OpenAI, Anthropic, Cursor, and Vercel all use this product to make their lives better.
它解决的问题是,当你构建SaaS或AI产品并想卖给其他公司时,你需要满足各种要求。
And the problem it solves is when you're building SaaS or an AI product and you want to sell to other companies, there's all these requirements you need to meet.
比如SSO、SCIM、RBAC、审计日志等等。
There's SSO, there's SCIM, there's RBAC, there's audit logs.
这些都是需要花时间集成的东西,但不是你应用的主要焦点。
These are all things that take time to integrate but aren't the main focus of your app.
WorkOS 是一个 API 层,让你只需几行代码就能满足所有这些要求。
WorkOS is an API layer that lets you meet all of these requirements in just a few lines of code.
比如说你有一个新的 SaaS 产品,想卖给其他公司,WorkOS 会帮你解决所有这些关键的功能缺口。
So let's say you have a new SaaS product and you wanna sell to other companies, WorkOS will solve all of these critical feature gaps for you.
你可以去 workos.com 了解更多并开始使用,我感谢他们支持我的工作并赞助这个播客。
You can check them out at workos.com to learn more and get started, and I appreciate them for supporting my work and sponsoring this podcast.
Atlassian 的 Jira 现在不只是用来跟踪工作了。
Jira by Atlassian isn't just for tracking work anymore.
现在你可以选择你最喜欢的 AI 代理来分配任务,它们能访问 Jira 中已有的丰富上下文。
Now you can pick your favorite AI agent to assign tasks to, and they'll get access to the rich context that's already in Jira.
当代理完成任务后,它会生成一个拉取请求。
When the agent is done, it surfaces a pull request.
这样,你就可以在一个地方用你最喜欢的代理做更多事情了。
That way you can get more done with your favorite agents all in one place.
更多信息请访问 jira.dev。
Learn more at jira.dev.
就是 jira.dev。
That's jira.dev.
感谢他们赞助本期播客,我们回到正题。
Appreciate them for sponsoring the podcast and back to the show.
我刚成为软件工程师,刚开始在 Facebook 工作的时候,他们有一个很流行的框架叫 Flow,是在 JavaScript 之上做类型推断的。
When I first became a software engineer and I went to start working at Facebook at the time, they had this popular framework called Flow, which was doing type inference on top of JavaScript.
这个东西当时要花很长时间。
It was this thing that would take a long time.
不过现在我已经很少听到它了。
And then I'd never hear about it these days.
所以听起来,如果要在 JavaScript 里做类型检查的话,TypeScript 赢了。
So it sounds like TypeScript won if there was a competition to type in JavaScript.
早期确实有一点竞争,是的。
There was a bit of it, yeah, in the early days.
我觉得我们之所以能行,其实是因为我们自己是自托管的,这让社区更容易参与项目。
I think the thing that worked for us was actually the fact that we were self hosted, which made it a lot easier for the community to contribute to the project.
我记得Flow是用CAML写的,所以你要给Flow做贡献的话,得去学一套完全不同的编程方式,还得用另一种语言,对吧?
Flow was written as I recall in CAML and so in order to contribute to Flow you had to go learn a whole different way of programming and in a different language, right?
而且Flow对IDE的工具也不太重视,这一点我们一开始就很清楚。
And Flow also didn't really focus all that much on IDE based tooling which we knew full well going in.
我们在写编译器,但我们写编译器不是为了生成机器码。
We're writing a compiler but we're not writing a compiler in order to generate machine code.
我们写它是为了做更好的工具。
We're writing it to make better tooling.
那才是我们写它的原因。
That was why we wrote it.
然后你看,和编译器配套的就是一个语言服务,它通过开放的协议深度集成到了Visual Studio、Visual Studio Code还有各种其他编辑器里。那其实就是需要解决的问题,对吧?
You know and so right there hand in hand with our compiler we had a language service it was deeply integrated into Visual Studio, Visual Studio Code, all sorts of other editors through an open protocol you know and that just that's where that was the problem that needed solving, right?
我的意思是,类型检查器不仅仅是有就好,问题是你真的需要它。
I mean, it's not it's nice to have a type checker, but boy, you want that.
你还想要语句补全。
You also want statement completion.
你想要红色波浪线。
You want red squigglies.
你想要,我是说,你想要交互式的体验,对吧?
You want I mean, you want it interactive, right?
我知道你在职业生涯中开发过多种编程语言。
So I know in your career you've worked on multiple programming languages.
开发一种编程语言需要什么?
What does it take to build a programming language?
首先,我要说,世界需要另一种编程语言,就像需要头上再开个洞一样。
Well, first I'll say that the world needs another programming language like it needs another hole in the head.
你得是某种特定类型的人,才会开始做这件事。
You've kind of got to be a certain kind of person to even embark on it to begin with.
这是计算机科学中一个非常迷人的领域,而且从计算机诞生之初就存在了。
It's a super fascinating area of computer science, and it's one that's been around ever since the beginning of computers.
展开剩余字幕(还有 374 条)
现在每个编译器、每种语言都有很多东西要了解,比如解析器、扫描器、词法分析器、代码生成器之类的,对吧?
Now every compiler, every language has a whole bunch of things you need to understand like parsers and scanners and lexers and code generators and whatever, right?
不过那只是实现语言本身的一些技术机制。
But that's sort of the mechanics of implementing the language.
然后还有语言的设计,也就是那种让它用起来很顺手的艺术感,对吧?
And then there's the design of the language, sort of the art of making it feel right, whatever, right?
我觉得这两方面你都得掌握。
And I think you sort of have to master both.
而且你得认识到,每门新语言其实只有百分之十是新的,剩下百分之九十都是其他语言也要做的苦差事。
And then you also got to appreciate that every new language is actually only 10% new, and then it's 90% the same drudgery that every other language has to go do.
所以要做好心理准备,有大量的工作可能没那么有意思。
And so be prepared for a lot of work that maybe isn't as interesting, you know.
最后我想说的是,永远不要忘记你是站在巨人的肩上的。
And then finally maybe I'll say that, you know, like never forget there that you stand on the shoulders of giants.
要打造一门真正好的编程语言,你必须先去深入了解很多其他的编程语言,还要理解不同编程风格之间的区别,比如过程式、面向对象、函数式等等。
I mean, in order to make a great programming language you got to understand a bunch of other programming languages first and understand all the all the distinctions between the different styles of programming like procedural and object oriented or functional or what have you.
最后但同样重要的是,这是一场持久战。
And then last but not least, it's like it's a long game.
我的意思是,这可能是比任何其他事情都更漫长的过程。
I mean, it is probably a longer game than anything else.
我参与过的每个语言项目,我都至少投入了十年,并且发布了多个版本。
I mean, like, every language project I've worked on, I've worked on each of them for at least ten years And shipped multiple versions.
而且真的要到第三版,它才开始真正变得像样。
And it's really never until version three that it truly starts to get okay.
你明白我的意思吗?
Do you know what I mean?
这真的需要极大的投入和坚持。
And it just takes an incredible amount of devotion to that.
所以,如果你不是一个能长期坚持解决一个问题的人,而是容易厌倦然后转向其他事情,那你就不适合做语言设计。
So you've got to really not be the type that tires of a problem quickly and then moves along that you're not meant to do language design.
你也会发现,当你和行业里的语言设计师交流时,他们都已经在这个领域做了很长时间了。
And you see that too when you talk to language designers in the industry, they've been doing it for a long time.
你提到了那两个部分。
You mentioned those two parts.
一部分是需要实现的具体功能,另一部分则是设计的艺术,让语言对开发者更友好。
There's the objective pieces that you need to implement, and then there's the art of the design and making the language, I guess, ergonomic for developers.
当你想到第二部分,也就是那种艺术,再看看其他编程语言,除了你自己参与过的那些,有没有你欣赏的?
When you think of that second part, that art, and you look at other programming languages, are there any that you admire outside of the ones that you've worked on of course?
学习和充分欣赏函数式编程的美,真的让我受益匪浅。
Learning and fully appreciating the beauty of functional programming has been very educational.
对吧?
Right?
我的意思是,这确实是一种不同的编程思维方式。
I mean because it really is a different way of thinking about programming.
这种思维方式更接近数学,而不是机器。
A way of thinking of programming that's much closer to math than it is to machines.
我认为从中产生了许多令人难以置信的好东西。
And I think there's a lot of incredible goodness that has come from that.
而且说实话,即使在构建TypeScript项目时,TypeScript编译器的大部分代码也是用高度函数式的风格编写的,并且使用不可变的数据结构,这些数据结构现在因为共享内存并发,可以在不同的线程或进程之间共享,而不会修改数据,因此它们可以共享同一个数据结构,对吧?
And then honestly, even in building TypeScript project, large portions of the TypeScript compiler are written in a highly functional style and work on immutable data structures that are then now, because of shared memory concurrency, can be shared between different threads or processes that don't mutate the data, and therefore they can share one data structure, right?
这非常强大。
And that's incredibly powerful.
但要掌握这一点,比如在命令式程序中写出纯函数式编程的孤岛,并将其与并发结合起来。
But mastering this, like writing islands of pure functional programming inside an imperative program and putting it together with Concurrence.
这很复杂,但我认为函数式编程给世界带来了很多好处。
I mean it's complex, but I think functional programming has brought a lot to the world.
面向对象编程也是如此,但我不想特别指出某一种语言。
And object oriented programming as well, I mean, but I wouldn't single out any particular language.
你接触到的每一种语言,你都能学到东西,你知道的。
Every one language you you come in contact with, you learn something, you know.
你提到世界并不真正需要更多的编程语言。
You mentioned the world doesn't really need more programming languages.
如果展望十年后,你觉得编程语言会比现在少吗?
And if you think ten years from now, do you think there'll be less programming languages than there are today?
这很难说。
It's hard to say.
我的意思是,但就像我说的,AI往往对现有的大玩家有利,对吧?
I mean, but like I said, AI tends to favor the incumbents, right?
而且我确实认为,这在AI出现之前就已经是这样了,成功实现一门编程语言并围绕它建立生态系统的门槛一直在提高。
And I do think, and I think this has been true even before AI, the bar keeps going up for what it takes to successfully implement a programming language and create an ecosystem around it.
以前,你只需要一个编译器就行了。
I mean, it used to be, oh, you just need a compiler.
现在,你还需要工具链。
Well, you also kind of need tooling now?
你需要语言服务。
I mean, you need a language service.
你需要调试器。
You need debuggers.
你需要性能分析器。
You need profilers.
你还需要框架和库。
You need frameworks and libraries.
你还需要能针对各种平台的代码生成器。我是说,事情变得越来越难了,你知道的,要想把这些全部搞定真的不容易。
You need code generators that can target all sorts of I mean, it's like it just keeps getting harder and harder, you know, to get all the way there.
嗯,当你想到所有这些组件时,它们其实都是为人服务的,我是说,IDE 和类型系统这些。
Well, when you think about all those pieces, they're really, they're all for the people, I mean, IDE and the types.
我是说,计算机也会看这些东西,但那是为了让我们能读懂源代码。
I mean, computer looks at that too, but it's so that we can read source.
也许有一天,大语言模型能直接生成机器码。
Maybe one day the LLMs will generate machine code directly.
我还真不好说。
I wonder.
我觉得,如果大语言模型不用反复重复自己,它们的表现会更好。
I think LLMs are better at what they do when they don't have to repeat themselves a lot.
你想啊,当程序用文本表达时,它最接近那种高度凝练的含义和表现形式,对吧?
Think like when a program is expressed in text it is closest to its sort of ultimate condensed meaning and representation, right?
要是把它翻译成机器码,里面会有大量噪音。比如那些指令里,有一半都是内存地址,跟这儿实际发生的事儿完全没关系,对吧?
If you translate it into machine code there's an awful lot of noise in that machine code like all of the instructions like half of the instructions are memory addresses that have absolutely no bearing on what's going on here, Right?
所以数据里已经有一半是噪音了。
So half of it half of all the data is noise already.
对吧?
Right?
然后你选哪个寄存器其实也没关系,代码生成器那边根本不在乎,而且说实话,随时都可能改主意。
And then whichever register you pick, well, that doesn't matter either in the code generator, and honestly, could change your mind at any point in time.
所以,要从那些噪音里把真相剥离出来,比直接面对一个变量名叫 i 之类的程序要难得多。
So so teasing the truth out of that noise is a lot harder than if you just have a program where the variable is called I and whatever.
而且,你还得能把它跟用户刚才给出的书面指令对应起来。
And by the way, that you can relate to the written instruction that the user just gave you.
我的意思是,你要记住,AI 在某种意义上只是人类的模拟器,对吧?
I mean, keep in mind that that, like, AI are they're they're just emulators of humans in a sense, right?
就像神经网络那样,对吧?
I mean, it's like neural networks, right?
我们之所以有编程语言,是因为我们根本没法直接从脑子里写出机器码,对吧?
There's a reason we have programming languages because we're terrible at writing machine code straight off out of our head, right?
AI跟我们也差不多,你知道吗?
AI is not that different from us, you know?
所以那边大概也是一样的道理。
So the same would probably be true there.
当你
When you
回顾一下你参与 C 语言和 TypeScript 这些语言项目的经历,那都是漫长的旅程。我想大家可能想知道的是,在这些旅程中你学到了什么?如果当初一开始就知道这些经验,你的起步会不会更顺利一些?
look back on working on C and TypeScript and these language projects, they were long journeys, and I think one thing people might want to know is what did you learn through those journeys that if you knew at the beginning of when you embarked on working on them, you might have been better off?
哎呀。
Gosh.
嗯,每个旅程都不太一样。
Well, each journey is is different.
我是说,比如我做的第一个项目 Turbo Pascal,我觉得那个项目开始于早期那种八位微机和 64K 内存的时代。那时候一个人就能搞定所有事情,对一切拥有绝对的控制权。
I mean, like the first project I worked on, Turbo Pascal, I I think that project started back in the old days when it was eight bit micros and 64 k of memory, and one person could do everything themselves and have ultimate control of everything.
所以我当时基本上就是一个人单干。
And so I was very much a one man shop.
对吧?
Right?
但很快这就行不通了。
But that quickly was not scalable.
对吧?
Right?
而且机器的容量也在变,我们从64K到了640K,然后一下子爆发了,对吧?
And and and capacities of machines, so we went for 64 to six forty ks, and then kaboom, the lid went off, right?
内存想要多少就有多少。
And you could have as much memory as you wanted.
所以一个人根本搞不定了。
And so not one person couldn't do it.
我不得不学会怎么跟团队合作,对吧?
And I had to learn to become a team player, right?
对我来说,那是一个很大的转变。
And that was a big journey for me.
我的意思是,学会放手,对吧?
I mean, to learn to let go, right?
如果你是个完美主义者,这可能很难。
If you're a perfectionist, could be hard.
但这是我在那里学到的一件事。
But that's one thing that I would say I learned there.
嗯,换个方式问这个问题就是,你觉得人们在开始构建编程语言时最常见的错误是什么?
Well, another way to word this question is, you know, what's the most common mistake that you see people make when they embark on building a programming language?
我觉得人们往往过于执着于一个想法,就是他们觉得,哦,如果我的语言能做这个那个,那不是很酷吗?
Well, I think people tend to over index on one idea, you know, that they have, that they think, Oh, wouldn't it be cool if my language could do blah?
然后他们忽略了所有那些每个编程语言都必须做的琐碎事情。
And then they under index on all of the mundane stuff that every programming language has to do, you know.
结果就是,他们喜欢的那件事可能做得更好,但其他所有事情都做得不够好。
And then it ends up doing that one thing they love, maybe better, but then it does everything else not as good.
所以总体来看,这反而是一个减分项,对吧?
And the net is a detractor, right?
所以你真的很难说清楚,实现一门编程语言的时候,有太多事情要做,而这些事情本身和你真正想解决的问题其实没什么关系。
And so it's so hard to convey how many things you have to do that really doesn't have anything to do with the problem you're trying to solve per se, you know, when you're implementing programming languages.
你在做 C 语言的时候,会去关注其他语言吗?看看它们哪些地方做得更好,以及 C 还能在哪些方面改进?
When you were working on C, do you keep tabs on the other languages and what they're doing better, what you could do better with C?
对,不关注不行,因为就像我说的,我们都是站在巨人的肩膀上。
Yeah, no, you gotta keep yourself informed about it because like I said, we all stand on the shoulders of giants.
没有哪门编程语言是在完全孤立的状态下创造出来的,对吧?
Programming language was ever created in perfect isolation, right?
每个人都在互相学习,然后有人提出一个好想法,之后你就会看到它被其他地方采纳。
Everyone learns from everyone and then someone comes up with a good idea and then you see it adopted elsewhere.
我们就在 C 语言里借鉴了很多函数式编程的思路,比如你懂的。
And we've adopted many ideas from functional programming, you know, in C, for example.
然后其他语言也采纳了一些我们在 C 语言里的好点子,比如异步,现在 JavaScript 和其他一些编程语言里也有,而这正是 C 语言率先开创的。
And then other languages have adopted some of the good ideas we had in C, like async, you know, now is in JavaScript and in some of the other programming languages out there and that was pioneered in C.
所以,你知道,我们互相学习,这真的是行业前进的方式。
And so, you know, we all learn from each other and that's how the industry moves forward, really.
你提到了,我猜,学会放手。
You mentioned the, I guess, learning to let go.
我觉得这是很多人在职业生涯中都会经历的事情,他们从个人贡献者做起,后来开始委派任务。
I think that's something that a lot of people as their career advances, they start with individual contributor work and then later they start delegating things.
你是怎么学会这个的,或者有没有一个故事或者某个项目,你放手了,然后你培养了这种技能?
How did you learn that or what was the is there like a maybe a story or a particular project where you let go and you kind of develop that skill?
嗯,这几乎就像是我有一个关于放手的反面故事,因为在C项目中,我的主要职责不是实现C编译器。
Well, it's almost like I got a counter story to letting go there because in the C project, my main function was not implementing the the C compiler.
而是作为语言设计师,编写规范,设计所有新的语言特性。
It was being the language designer and writing the spec and designing all the new language features.
在那之前,我在做Turbo Pascal的时候,我做了很多实际的编码工作,对吧?
And before that, when I had worked on Turbo Pascal, I was doing a bunch of active coding on the thing itself, right?
但后来我有点放手了。
But then I sort of let go of that.
但我放手放得太过了,有点飘到平流层去了,变成了一个架构宇航员。
But I let go of it too much, and I sort of drifted up into the stratosphere and became more of an architecture astronaut.
你懂我的意思吗?
Do you know what I mean?
而且我不再亲自动手了。
And I wasn't getting my hands dirty.
我在框架和库里写东西,但这些都不是真正难解决的大问题,对吧?
I was writing stuff in the framework and in the libraries, but it didn't quite these are not like the deep really super hard problems to solve, right?
我当时没意识到,但我渐渐对所做的工作不那么满意了,对吧?
And I didn't really know it at the time but I was gradually getting less happy with the work that was doing, right?
我虽然还是喜欢,但总觉得少了点什么。所以当TypeScript这个机会出现时,我决定跳进去,真正参与编译器的工作。
I mean I still enjoyed but there was something missing, And so when this TypeScript opportunity came along, I decided to jump in and actually actively participating in Compiler.
这给我的生活带来了很多快乐。
And it brought so much happiness to my life.
我终于意识到,我就是个快乐的程序员。
I finally realized I'm just a happy coder.
我也喜欢规范相关的工作,但写代码才是让我早上起床的动力,煮杯咖啡,写点代码。
I like the spec stuff too, but coding is like, man, that's what gets me up in the morning, make coffee and write some code.
那才是我最开心的时候。
That's when I'm in my happy space.
当人们达到非常非常高的级别时,他们往往会对影响力有一定的期望。
When people are at these really, really high levels, they kind of have this expectation of a certain level of impact.
那么,作为这么高级别的工程师,你怎么继续写代码呢?
And so how do you continue to write code as such a high level engineer?
嗯,我写的具体代码不一定有这么大的影响力,但重要的是我也参与架构指导,你知道,作为项目团队的一部分。
Well, the specific code I'm writing isn't necessarily having all that impact, but it's the fact that I also do the architectural guidance, you know, as part of a group of people, right, in a in a project.
你知道,工作机会很多,大家都有事做,然后你只需要保持参与项目的某个角落,这样你就能看到代码里发生了什么。
You know, there's plenty of work for everyone to go around, and then you you just but you you you stay involved in a corner of the project because then you see what happens in the code.
你知道,当你提交代码的时候,你会想,那边是什么?
You know, when you're checking in your code, you go, what was that over there?
让我看看这边发生了什么?
Let me just what's happening over here?
或者你突然发现,哎,这个得重构一下了。
Or you realize, oh, we need to refactor this.
现在感觉不太对劲了。
This is not feeling right anymore.
但如果放手了,你就没法真正去谈大家每天都在用的那个东西。
But if you let go of that, you can't really talk about the thing that people use day to day.
你可以谈那些东西表面的语法,但你谈不了那个东西本身。
You can talk about the syntax of the thing that people use day to day, but you can't talk about the thing.
我觉得两者都很重要,而且我很高兴现在能两样都做。
Both are important, I think, and I'm happy that I get to do both now.
我知道很多公司都有工程角色分类这种说法,也谈资深工程师是怎么干活的。你刚才提到架构师,其实很多公司对架构师有不同的叫法。
I know a lot of companies have this idea of engineering archetypes or the way that high level engineers get some work done and you mentioned architect for instance, a lot of companies have different words for architect.
我不太确定你是只说这是你的个人工作风格,还是认为所有资深工程师都该保持一定程度的动手能力?
I'm not sure if you're saying it's just your working style or are you saying that all high level engineers should be hands on at some level?
不,我不是那个意思。我是说,这是我主动选择继续做独立贡献者,而不是去当管理者。
No, I'm not saying that because I don't think it's like I made a conscious choice to remain an independent contributor as opposed to become a manager.
我是说,我有很多机会,但那不是我发挥最好的地方,对吧?
I mean I have plenty of opportunities but that is not where I do my best work, right?
所以我觉得你得自己决定,什么能激励你,让你开心,让你愿意一辈子做这件事。
So I think you have to decide for yourself what is it that motivates you, makes you happy, keeps you doing this for a lifetime.
你明白我的意思吗?
Do you know what I mean?
而且人生只有一次机会,你知道吗?
And you only get one run at it in life here, you know?
如果你想做出最好的成绩,我觉得就去做最让你开心的事。
And if you're gonna do your best work, do the thing that makes you the most happy, I think.
这就是我一路走来学到的,编程是其中一部分,而且是很大的一部分。
And that's what I learned along the way there, that coding is part of that, a big part of that.
那么,当你在做C语言但还没接触TypeScript的时候,你是怎么知道缺少了什么呢?
So then when you were working on C but before TypeScript, like how did you know something was missing?
我就是知道。
I just knew something.
我也不知道怎么说,就是光做设计那块儿,我感觉没那么有成就感。
I don't know how, I mean, just, I just wasn't feeling as fulfilled with only doing the design part.
对吧?
Right?
我还是挺想念写代码的感觉的,只要有机会能敲几行代码,我就觉得特别开心,心想这还挺有意思的。
I missed the coding and whenever I had a chance to write a little bit of code I would feel a lot happier and I go, it's kind of interesting.
你知道我是啥意思吧?
Mean, do you know what I mean?
不过现在我得去写更多的规格说明文档了,你懂的。
But now I gotta go write some more specs, you know?
那后来转向 TypeScript,是不是因为你想多写点代码?
So then was TypeScript something you kind of went towards because you wanted to write more code?
嗯,我选择它是出于好几个原因。
Well, I went towards it for many reasons.
说实话,一开始并不是专门为了这个才去的。
I mean, it wasn't specifically that to begin with.
我就是觉得这个问题很有意思,对吧?
I just found the problem fascinating, right?
因为TypeScript的出现其实间接和C有关。我记得好像是outlook.com团队找到了C团队,问能不能帮他们把Script Sharp产品化。
I mean, because the way TypeScript came about was actually indirectly through C because the outlook.comteam I think it was approached the C group and asked whether we would pretty please productize something called Script Sharp.
Script Sharp这个东西能把C代码转成JavaScript,这样就能在浏览器里运行了。
And Script Sharp was this thing that took C and transpiled it into JavaScript so you could run it in a browser.
我当时就想,什么?
And I'm like what?
为什么要这么做呢?
Why would you want to do that?
为什么不直接写JavaScript呢?
Why don't you just write the job?
因为那样的话,我们就能有很好的工具支持。
Well because that way we can get great tooling.
我们可以用Visual Studio,可以有项目,有类型检查,有代码重构和导航,还能写接口,大家就能明白整个系统是怎么运作的了。
Then we can use Visual Studio and we can have projects and we can have type checking and we can have code refactoring and navigation and we can write interfaces and people can understand how this all works.
我当时心想,哇。
And I'm like, wow.
JavaScript真的烂到那种地步了吗?
Is JavaScript really that busted?
然后你说,想解决这个问题,就得把JavaScript抛弃掉,把它当成一种指令语言。
And and you're saying, like, the the way you wanna fix that problem is by abandoning JavaScript, treating it as an instruction language.
对吧?
Right?
然后再让一个代码生成器去针对它。
And then having a code generator target it.
我就想说,那能不能直接修修JavaScript呢?
I'm like, couldn't we like fix JavaScript?
那不是更好吗?
Wouldn't that be better?
你懂我的意思吗?
Do know what I mean?
所以TypeScript就是这么起步的,对吧?
And that's how TypeScript kind of got off the ground, right?
当时就觉得,JavaScript工具链确实有些地方问题很大,必须得修,对吧?
It was like, gosh, there's something here that's really broken that needs to be fixed, right, when it comes to JavaScript tooling.
这就是我们当初的目标。
And that's what we set out to do.
你知道吗,我觉得有个话题挺有意思的,就是你在一次演讲中提到,因为AI的原因,现在工具的速度比以前更重要了。
You know, one thing I thought would be interesting is in one of the talks that you gave, you said that you believe that the speed of your tooling is more important now because of AI.
我想听听你的看法,为什么这么说?
And I want to hear your thoughts on why is that the case?
嗯,现在越来越多的
Well, more and
工作流程都是由那些在后台自动运行的代理来主导的,对吧?
more our workflows now are are dominated by agents that are, like, running away in the background, right?
对吧?
Right?
我的意思是,就像帮你写代码一样。
I mean, like writing code for you.
它们会像我们一样犯错,但你可以想要多少就有多少。
And they make mistakes just like we do, but they but they but, you know, but you can have as many of them as you want.
所以生态里有很多很多的小工在写更多的代码,对吧?
So there are like many, many more little workers in the ecosystem writing much more code, right?
而且整个工作流,LLM本身就已经有性能挑战了。
And that whole workflow is like LLMs already have performance challenging.
然后如果你在一个大项目里写代码,每次LLM写点东西你都得做类型检查,每次都要花两分钟,你懂我的意思吗?
Then if you add like, if you're writing code in a big project and you have to like type check it and it takes two minutes every time the LLM writes something, do you know what mean?
那太糟糕了,对吧?
That's horrible, right?
所以让这个过程更快是个很大的好处。
So making that go faster is a big benefit.
对,完全同意。
Yeah, absolutely.
我想是因为它在不停地运行。
I guess because it's hammering away.
对,我是说,我们都知道大语言模型喜欢用 GREP 之类的工具,对吧?
Yeah, I mean like well we all know LLMs they like to use GREP and and whatever right?
但现在它们也足够聪明了,能意识到如果你试图修改一个叫 version 的属性,而每个其他对象都有这个 version 属性,你就不能简单地搜索 version 然后把它重命名为别的名字,因为这样会破坏所有包含 version 的其他接口。
But then they're also smart enough now to realize that if you're like trying to change this property called version and like every other object has a version property You can't just grep for version and then go rename it to something else because like you're breaking all these other interfaces that have a version in them.
对吧?
Right?
所以你得做语义搜索,而能进行语义搜索的只有编译器。
So you got to do semantic search and the only thing that can do semantic search is a compiler.
因此你通常需要通过 LSP(语言服务协议)、语言服务,或者通过我们的命令行工具来调用编译器,后者能提供等效的功能,对吧?
And so you got to use the compiler through typically through LSP, through language services, or through our command line tool that would give you the equivalent, right?
现在越来越多的 AI 都在做这件事了。
And so more and more AI is doing that.
这意味着什么呢?你知道的,编译器在后台运行,你可能根本察觉不到它们在工作,但它们确实在跑。
And that means, you know, compilers run at you don't you may not even see that they're running, but they're running.
而且它们是在替你干活。
And they're doing work on your behalf.
对。
Yeah.
你聊AI的时候,讲得非常实际,而且跟软件工程结合得很紧密。
When you talk about AI, it's very realistic and grounded in the software engineering.
所以我觉得,不如拿一些我在网上常听到的关于AI的说法,来听听你的看法,看看这些说法有多准确,以及你觉得它们什么时候会成真,或者会不会成真。
And so I thought it might be interesting to run some common AI takes that I hear from the internet and get your sense of how accurate is this, what are your thoughts on when or if it'll be true.
好。
Okay.
第一个我听到的说法,去年年底比较流行,就是说AI会在一年内写出90%以上的代码。
So the first one that I've heard, this was more common at the end of last year, is that AI is gonna write 90 plus percent of the code, you know, within a year.
我想听听你怎么看。
Curious what you think on that.
嗯,对于某些类型的应用来说,可能我写的代码里,AI已经写了100%了,对吧?
Well, for certain classes of apps, might be like all of I coded apps are writing 100 of the code, right?
而且现在确实有大量这类代码被写出来了。
And there's an awful lot of that being written.
他们真能写出互联网上90%的高质量代码吗?
Are they gonna write 90% of the high quality code on the Internet?
这个我还真不好说。
I don't know about that.
关键是,90%的什么东西呢?
So the thing is, like, 90% of what?
现在写出来的代码量简直像这样蹭蹭往上涨,对吧?
The volume of written code is just, like, going like that right now, right?
因为 AI 写的代码太多了。
Because AI writes so much code.
所以从这个意义上说,这成了一个自我实现的预言,对吧?
So in a sense that's a self fulfilling prophecy, right?
我是说,但如果是那种以前从未有人写过、质量要求极高的代码,我不觉得 AI 能写出其中 90%。
I mean but when it comes to like the super high quality code that no one has ever written before, it's not clear to me that AI is going to write 90% of that.
那么,当你想到AI没有编写所有代码的情况时,也许有一些超高水平的例子。
So when you think about cases that AI is not writing all the code, Maybe some examples of the super high quality stuff.
那是什么?
What is that?
嗯,我的意思是,比如以前从未见过的算法,或者特定的解决方案,比如我知道AI无法编写我们的编译器,TypeScript编译器。
Well, I mean it's algorithms that no one has ever seen before, for example, or particular solutions like mean I know that AI could not write our compiler, the TypeScript compiler.
它就是做不到。
It just can't.
我们试过了。
I mean, we've tried.
它做不到。
It can't do it.
我也没要求它去做。
And I'm not asking it to either.
我也不指望它能做到。
I mean, I'm not expecting it to either.
但我们的编译器也不是一段典型的代码。
But our compiler is also not a typical piece of code.
我的意思是,这就是为什么它写不好,因为它在训练集里没见过这样的代码。
I mean, that's why it's bad at writing it because it's seen none of it in the training set.
嗯,我见过一些编译器,但不是这样的,没有这些概念,也不是我们这种实现方式,对吧?
Well, I've seen some compilers, but not like this one, not with these concepts, not with done the way that we're doing it, right?
所以它在这里并不适用。
And so it's just not a good fit there.
我们不能忘记,AI本质上是一台巨大的随机机器,它记住了整个互联网,对吧?
AI we can't forget that AI is, at heart, a big stochastic machine that has memorized the entire Internet, right?
而且它能在一定程度上根据记住的内容进行推断,对吧?
And has an ability to extrapolate somewhat over what it's memorized, right?
但如果它以前没见过,它不一定能做得很好。
But if it hasn't seen it before, it's not necessarily going to be all that good at doing it.
它在进步。
It's getting better.
我不是说它不厉害。
I mean, I'm not saying it's not impressive.
它能做到的事情确实非常惊人。
Wildly impressive what it can do.
但我还是觉得,离它完全搞定所有事情还有很长的路要走。
But I just think there's a long way still to it's doing all of it.
而且我也不确定我们能不能走到那一步。
And I don't know that we ever get there.
我希望我们别走到那一步,不然人类还有什么意义呢?
I hope we don't because then what's the point of humans anymore then?
我是说,确实。
Mean it's.
我经常看到这种说法,就是说,你一年内就不需要再用IDE了,或者你都不用再看代码了。
What I see this take often too is, you know, you won't need to use an IDE within the year, or you don't need to read the code anymore.
那祝你好运吧。
Well, good luck to you.
我的意思是,如果你要把钥匙交给AI,那一切就都说不准了。
I mean, if you're gonna hand AI the keys, I mean then all bets are off.
对吧?
Right?
我的意思是,一旦AI不能说服它去修复你想要的这个问题或者新功能,那你打算怎么办?
I mean the minute AI you can't convince AI to fix this issue or this new feature that you want built, what are you gonna do?
我的意思是,如果你不理解底层的东西,对吧?
I mean if you don't understand what what's below, right?
那是一个问题。
That's one problem.
另一个问题是,假设一个用户来找你说,你的应用偷了我的银行账户。
The other problem is let's say a user comes to you and goes, your app just stole my bank account.
那,他们会起诉你。
Well, it's gonna sue you.
他们起诉的是你,不是AI。
It's not they're gonna sue you, not the AI.
说到底,总得有人为AI的行为负责。
I mean, it's like at the end of the day someone has to take responsibility for what AI is doing.
如果你把控制权交给它,那责任就在你身上。
And if you're giving it the keys, well, it's on you.
你明白吗?
You know?
但是,我也不确定。
But but I don't know.
我个人会觉得很不自在。
I personally would not feel comfortable.
我晚上会睡不着觉。
I wouldn't be able to go to sleep at night.
如果我不清楚自己在担保什么的话。
I mean, if I didn't understand what it is that I am vouching for.
为什么这个观点和我在Anthropic工作的人那里看到的差别这么大?
Why is there such a big difference between this opinion and what I see from maybe people who work at Anthropic?
区别在于,我并不是说AI做不了了不起的事情。
Well the difference is, all I'm saying here is not that AI can't do amazing things.
它确实能,每天都在做。
It does, it can, it does that every day.
但人们就是喜欢把它推到百分之百,对吧?
But people love these like take it all the way to 100%, right?
而这就是我有点不认同的地方,对吧?
And that's where I get off the bus a little bit, right?
我觉得,好吧,我们可以把比例提得越来越高。
I think, oh yeah, okay fine, we can get higher and higher percentage.
但总得有人理解正在发生的事情,以及它如何与我们的业务问题相关,如何与我们组织的目标相契合。
But there still has to be someone understanding what's going on and how it's relevant to our business problem and how it relates to what our organization is doing.
还有很多其他东西需要连接起来,所以我认为仅仅把AI看作包办一切、我们完全多余,这是不对的。
There's so many other things that have to be connected that it's I think it's wrong to just view it as AI did it all and we were completely unnecessary.
对,我接下来想问你的是,三年后,AI会取代初级软件工程师吗?
Yeah, the next one I was going to ask you was, three years from now, will AI replace junior software engineers?
或者初级软件工程师现在做的事情?
Or what junior software engineers do today?
如果真是这样,那高级软件工程师从哪来?
Well, if it does, then how do you ever get senior software engineers?
对吧?
Right?
我觉得不会。
I mean, it's just like I don't think so.
除非你也相信,没有高级软件工程师,你的业务还能再撑三年。
Well, I'm not unless you also believe that you will be able to do your business three years later than that without any senior software engineers.
因为他们从哪来?
Because where are they going to come from?
你得培养他们。
You got to train them.
但在我看来,某种程度上已经发生的是,对于某些类型的程序员,金字塔的底部已经变窄了。
But to me, I think maybe one thing that to some extent has happened is that for certain classes of programmers, pyramid has narrowed at the bottom.
现在进来的人少了。
There are fewer people coming in.
我们希望他们更快地往上走,这样他们就能承担更多的管理职责。
And we are wanting them to advance higher up faster so that they can get to this more supervisory role.
我觉得软件工程师这个职业确实在变化,从你自己敲代码,变成让AI代理敲代码,然后你来审查它们的工作。
I think the craft of being a software engineer is definitely changing from your typing in lines of code to you're having agents type in lines of code and you are reviewing the work of the agents.
对吧?
Right?
所以你做更多的审查,少敲代码。
And so you do more reviewing, less typing.
有些人很喜欢这种工作方式,而且确实做得很好,对吧?
And some people love that, you know, I mean and really are fantastic at that workflow, right?
但这改变了程序员工作的本质,你工具箱里的这个新工具带来了这种影响。
But it's a change in nature of what the job looks like as a programmer and this tool that you now have in a toolbox is having that impact.
但它终究只是一个工具,而且在这个过程中仍然有程序员参与。
But it is but a tool And there are still programmers involved in process.
这一点我深信不疑。
That I firmly believe.
听起来你很喜欢亲手敲代码。
Sounds like you enjoy typing out the code.
如果五年后,你会不会没那么开心?
Would you be less happy if five
四十年、五十年了,我一直很喜欢敲代码。
For years from now it was forty, fifty years I have enjoyed typing out code.
其实,有些部分我还是会继续自己敲,你知道的。
I'm actually there are some and so I will continue to type certain parts of the code, you know.
但有些代码部分,我就不太想自己写了。
But there are other parts of the code that I don't particularly care to type.
比如写测试,还有遵循那些测试框架的各种严格规范,我就不太想碰。
I don't care to type in tests and follow all the rigor of the particular testing framework.
那当然不想,如果能交给AI去做,我求之不得。
Heck no, if I can farm that out to AI, happy me.
你知道吗?
You know?
我确实觉得审阅代码对我来说一直比较难。
I do think reviewing has always been harder for me.
比起写代码,我更不愿意花时间在审阅别人的代码上。
It's harder for me to like spend time on reviewing other people's code than it is, you know writing the code.
但我也觉得,随着时间的推移,我们可以让代码审阅的过程比现在更省力。
But I also think that over time we will we can make that process of reviewing code much more ergonomic than it is today.
我的意思是,现在通常你只会看到改了哪些文件,以及这些差异。
I mean often today you just get here's like the list of the files that were changed and here are the deltas.
你自己去琢磨吧。
You figure it out.
就这样。
Out.
AI可以在那方面帮我们更多,比如解释这些改动是什么之类的。
AI could help us more there by explaining what the changes are and whatever.
所以我觉得我们会变得更好。
And so I think we're going to get better.
这会变得更有意思。
This is going to get more interesting.
但这会改变这门手艺的本质。
But it will change the nature of the craft.
你说你写代码已经写了四十年,可能五十年了。
You said that you've been writing code for forty, maybe fifty years.
你写过的最难的一段代码是什么?
What is the hardest piece of code you've ever written?
或者你做过的最有技术挑战性的事情是什么?
Or what's the most technically challenging thing you've ever done?
有很多事情在当时都很有挑战性,你知道的。
There are so many things that in their time were challenging, you know.
就拿我们最近做的这个项目来说,我们知道简单的部分就是把原生代码迁移到另一种语言,但真正难的是处理共享内存并发这个难题,还要让编译器充分利用你机器上所有的CPU。
I mean this last project we worked on, we knew that like you know sort of the easy part was getting the native code that's just like just move it to this other language right but then this taming this beast called shared memory concurrency and and getting the compiler to use as many CPUs as there are available on your box.
对吧?
Right?
在编译器里解决这个问题可不简单,因为我们学的都是写顺序执行的代码。
That is not a simple problem to solve in a compiler because we're all taught to write sequential stuff.
对吧?
Right?
我的意思是,先做这个,再做那个,但你怎么能同时做所有这些,然后之后共享数据结构,而不让别人意外修改你的数据结构呢?
I mean, first you do this, then you do this, but how do you do all of this at the same time and then share the data structures afterwards without anyone accidentally modifying the other guy's data structure?
在必须这样做的情况下,你怎么同步,避免死锁、竞态条件等等,对吧?
How do you in the cases where you have to do that, how do you then synchronize it and avoid deadlocks and race conditions and whatever, right?
这确实棘手。
It was tricky.
我们解决了一些很好的技术难题,我觉得我们可以为此感到自豪,你知道吗?
There were some good technical problems that we licked that I think we can be proud of, you know?
那在你职业生涯早期,硬件资源更受限的时候呢?
What about when hardware was more constrained earlier in your career?
有没有什么特别奇葩的操作,就是为了让它能跑起来?
Is there any wacky thing you had to do to kind of make it work?
哦,那当然有。
Oh totally.
我是说,我刚入行那会儿,当程序员跟现在完全是两码事,对吧?
I mean, when I started, was a like being a programmer was a very, very different thing, right?
我一开始用的是八位微处理器,里面固化了微软的BASIC和ROM。
I mean, I started out with eight bit micros that had Microsoft BASIC and ROM.
对吧?
Right?
然后有BASIC解释器,你可以买那种书,把里面的星球大战游戏代码敲进去,之类的。
And then the BASIC interpreter, and you could buy these books and type in these Star Wars games or whatever.
那些游戏全是文本的。
They were all text.
你懂吧?
You know?
就是滚动显示,告诉你那个象限里有克林贡人,你知道,还有K4什么的。
They're just scrolling and telling you there's Klingons over in that quadrant, you know, and k four, you know, and you got whatever.
对吧?
Right?
但我对理解这一切是怎么组合在一起的着了迷,然后很快就学会了写汇编代码。
But I got fascinated with understanding how it was all put together and and got and and quickly learned how to write assembly code.
而Turbo Pascal,我参与的第一个产品,完全是用z80汇编写的。
And Turbo Pascal, the first product I worked on, was all written in z80 assembly code.
编译器、编辑器、运行时库,全都是汇编。
The compiler, the editor, the runtime library, everything was assembly.
用汇编写编译器,那真是费了老大的劲,你知道吗?你得算着,比如,我想,我得把这个塞进EPROM里,但只有12K的空间,而我超了20字节。
And writing structured, a compiler in assembly code is like, that was, that was like, took a lot of fiddling, you know, and I mean, and you were counting like, okay, I think I can, I need to, we need to squeeze this into this eprom and then there's only 12 ks, you know, and I'm I'm 20 bytes over budget here?
哦,但我可以把那个长跳转改成短跳转,然后跳到那个跳转,再跳到那个跳转,这样就能省一个字节。
Oh, but I can make this jump this long jump instead, I could jump to this short jump and then jumps to that jump, and then I could save one that's one byte saved.
好。
Okay.
你知道,继续往下说。
You know, moving right along.
我的意思是,你会一直坐在那儿琢磨来琢磨去。
I mean and you you would you would you would you would just, like, sit there fiddling.
你知道吗?
You know?
那真是一门手艺。
It was it was a craft.
几乎就像木工活一样。
It was like woodworking almost.
我是说,跟我们现在做的事情完全不一样。
I mean, it was just so different from what we do now.
对吧?
Right?
现在一切都变了。
Everything is now.
用户的需求和期望都是无底洞,对吧?
It's bottomless pits of capacity and bottomless pits of expectation from users, right?
你有没有一本特别推荐给软件工程师的技术书?
Is there a top technical book recommendation you have for software engineers?
我通常推荐同一本,但对我年轻时来说,那本最重要的书是……
I usually recommend the same, but the one book that was like the it book for me when I was younger.
叫《算法与数据结构程序》,作者是尼古拉斯·维斯,帕斯卡语言的发明者。
And it's called Algorithms plus Data Structures Programs by Nicholas Wies, the inventor of Pascal.
后来他还发明了Modula和Oberon之类的语言。
And then later Modula and Oberon and whatever.
这本书数学和符号内容不多,但有很多教学实例,对数据结构的工作原理解释得很清楚。
And it's a book that is light on math and symbolism and rich in instructive examples and good explanations about how data structures work.
我就是从这本书学到哈希表的,对吧?
I mean, that's how I learned about hash tables, right?
你知道,自学的话,你根本不知道哈希表是什么。
I mean, like, when you're self taught, you don't know about hash tables.
你大概知道链表是什么,对吧?
You sort of know about linked lists, right?
那还好。
And fine.
所以在最初的Turbo Pascal版本里,所有的符号表其实都是链表,你知道的,或者类似的东西。
So in the original version of Turbo Pascal, all the symbol tables were just, well, they were just linked lists, you know, or whatever.
然后,当然,当你有许多局部变量时,搜索时间会呈指数增长,你知道的。后来我读到关于哈希表的内容,哇,什么?
And then, of course, as you had many local variables, well, you're a lot you're you're you're you're going exponential in search time to, you know and then I read about these hash tables and like, wow, what?
你是说我可以这样做,然后基本上就是线性查找时间,实现之后编译速度翻倍了。
You mean I can, like, just do this and then, like, it's it's basically like linear lookup time and implemented and the compile went twice as fast.
对吧?
Right?
天哪!
Like, holy cow!
你知道,那真是有用的阅读,你懂我的意思吗?
You know, that was useful reading, do know what I mean?
所以我一直就是那种工程师的角色。
So I was always like the engineer.
关于怎么做错误恢复,他在《如何构建一个简单的编译器》里讲得很清楚,对我来说那真是一本好书。
How to do error recovery, he explains that in like how you construct a simple compiler and then like, and it was for me a great book.
现在这本书其实就是一个大的PDF文件,你可以从网上下载到。
And now it's actually, it's just a big PDF, you can download it out there.
这本书已经绝版三四十年了。
It's out of print since forty, thirty years.
最后一个问题,以你现在的经验,如果回到刚入行的时候,给自己一些建议,你会说什么?
Last question for you is, with all the experience that you have now, if you go back to yourself when you just entered the industry and give yourself some advice, what would you say?
嗯,可能有几件事吧。
Well, a couple of things, maybe.
我们之前聊过团队合作。
We talked about being a team player.
我可能会一开始就多学一些关于团队合作的东西。
I would have probably tried to educate myself a bit more about that to begin with.
我觉得还有一点,回顾起来就是,别让别人告诉你这事做不成。
I think also one thing in retrospect is don't let people tell you that it can't be done.
他们告诉你做不成,是因为他们自己做不了。
When they tell you it can't be done it's because they can't do it.
那不代表你也做不了。
That doesn't mean that you couldn't possibly do it.
你明白我的意思吗?
Do know what I mean?
所以别让那些话打击你。
So don't let that discourage you.
有没有哪个项目,别人说你做不成,结果你做到了,然后就这样……
Is there a project where you someone said you couldn't do it, and then you did it, and that's how you
嗯,我觉得我做的第一个项目,就是Turbo Pascal,每次我们跟别人说我们做的东西,他们就说,这不可能。
Well, I think the first thing I worked on, like Turbo Pascal, people were telling me whenever we told them, here's what we have, they said, that can't be done.
他们就是那种,哎呀,不可能。
That's like, nah.
你们这些人,真是胡说八道。
You guys are you're full of shit.
那根本不可能。
That's like not possible.
你知道吗?
You know?
嗯,但确实做到了。
Well, it was.
而且我当时并不知道那不可能。
And I didn't know that it wasn't possible.
对吧?
Right?
太棒了。
Awesome.
好的,感谢你抽出时间。
Well, thank you for your time.
安德斯,我真的很感激你。
I really appreciate it, Anders.
不客气。
You're welcome.
哪里的话。
No.
这真的很有意思。
This is a lot of fun.
嘿。
Hey.
感谢大家收看这期播客。
Thank you for watching this podcast.
如果你喜欢这期节目,想看到它越做越好,请点赞或留言支持一下。
If you liked it and you wanna see the show grow, please support with a comment or a like.
另外,如果你有想让我邀请的嘉宾人选,也请在评论区留言。
Also, if you have any recommendations for people you want me to bring on, please drop a comment.
像芭芭拉·利斯科夫、迈克·斯通布雷克、马克·布鲁克这些嘉宾,都是因为有人留言推荐,我才请来的。
Guests like Barbara Liszkoff, Mike Stonebreaker, Mark Brooker, these were all people that I brought on because someone left a comment.
另外,除了播客,我还在做一款我一直想要的人体工学键盘。
On another note, aside from the podcast, I'm working on building the ergonomic keyboard that I wish existed.
这是原型机的样子。
Here's a glance at the prototype.
它是分体式键盘,所以有左右两部分。
It's a split keyboard, so there's two sides.
这不是最终的外壳。
This isn't the case.
不过,我们在Kickstarter上发起了众筹,上线八小时内就达成了目标。
But, yeah, we launched on Kickstarter, and we hit our goal within eight hours of launching.
如果你也抢到了早期版本,我真的很感谢。
I really appreciate it if you were one of the people who grabbed one of the early units.
我们现在正在为制造工具做长期准备。
We're now working on the long journey of building the tooling now.
所以如果你还想买一个,我在Kickstarter上保留了后期认购的通道。
And so if you still wanna pick one up, I've left the late pledges open on Kickstarter.
你可以在那边下单购买。
So you can grab one there.
我会在描述里放上链接。
I'll put a link in the description.
再次感谢收看本期播客,我们
Thank you again for watching the podcast, and I'll see you
在
in
下一期节目中见。
the next episode.
关于 Bayt 播客
Bayt 提供中文+原文双语音频和字幕,帮助你打破语言障碍,轻松听懂全球优质播客。