Why Common Lisp is now the best programming language
Why Common Lisp is now the best programming language
为什么 Common Lisp 现在是最好的编程语言
Would you agree that some programming languages are better than others? If so then one of them must be the best. And it’s actually Common Lisp especially now that LLMs can write code. 你是否认同某些编程语言比其他语言更好?如果是这样,那么其中必然有一种是最好的。而这个“最好”的语言实际上就是 Common Lisp,尤其是在大语言模型(LLM)能够编写代码的今天。
LLMs write code really fast, and that changes a lot, because writing code used to be the slow part. Now the slow part is finding out if your program actually works, and before you can do that you have to rebuild it, which can take a few minutes. When humans wrote the code this didn’t matter much, because writing took way longer than waiting for it to compile and start running. But now it does, so how long your feedback loop takes is what decides how fast you can build. LLM 编写代码的速度非常快,这改变了一切,因为过去编写代码才是最耗时的环节。现在,最耗时的是验证程序是否真正有效,而在验证之前,你必须重新构建它,这可能需要几分钟。当代码由人类编写时,这并不重要,因为编写代码的时间远长于等待编译和运行的时间。但现在情况变了,反馈循环的时长决定了你的开发速度。
In Common Lisp that loop almost doesn’t exist because there is no real distinction between read-time, compile-time, and runtime (Graham). Common Lisp is image-based which means that your program is a live image in memory, so a new version of a function replaces the old one right away without having to restart anything. 在 Common Lisp 中,这个循环几乎不存在,因为读取时、编译时和运行时之间没有真正的界限(Graham)。Common Lisp 是基于镜像(image-based)的,这意味着你的程序是内存中的一个实时镜像,因此函数的新版本可以立即替换旧版本,而无需重启任何东西。
Also, in most languages an error will crash your program. So if you’re writing code with an LLM it will have to read your crash logs to make some changes and run your program again. In Common Lisp your program won’t crash, it’ll stop and open a debugger with the whole stack and all the variables. You can just point your LLM at the debugger, and it’ll make its fix and resume the program. To my knowledge Common Lisp is the only mainstream language that does all of this. 此外,在大多数语言中,错误会导致程序崩溃。因此,如果你使用 LLM 编写代码,它必须读取崩溃日志来进行修改并重新运行程序。而在 Common Lisp 中,程序不会崩溃,它会暂停并打开一个包含完整堆栈和所有变量的调试器。你可以直接让 LLM 查看调试器,它就能进行修复并恢复程序运行。据我所知,Common Lisp 是唯一能做到这一切的主流语言。
Lisp stands for “List Processing.” In Common Lisp, code is written as lists. For example, (+ 1 2) is a program that adds two numbers, but it’s also just a list of three things: the symbol +, and the numbers 1 and 2. What’s interesting is that this is the same kind of list Common Lisp uses to store data, and since the language is built around processing lists all its tools for working with data also work on code.
Lisp 代表“列表处理”(List Processing)。在 Common Lisp 中,代码以列表形式编写。例如,(+ 1 2) 是一个将两个数字相加的程序,但它同时也是一个包含三个元素的列表:符号 + 以及数字 1 和 2。有趣的是,这与 Common Lisp 用于存储数据的列表类型相同,由于该语言是围绕处理列表构建的,因此它所有用于处理数据的工具同样适用于代码。
So a program can take another program and change it, for example it can turn (+ 1 2) into (* 1 2), and run the result right away. This is what makes macros possible. A macro is a function that takes your code and returns new code in its place, that means you can add new constructs to the language itself. Once you can add to the language, you can build it up toward your problem. So in Lisp you don’t just write a program, you write a language for your domain and then write the program in it.
因此,一个程序可以获取并修改另一个程序,例如它可以将 (+ 1 2) 变为 (* 1 2),并立即运行结果。这就是宏(macros)的实现原理。宏是一个接收你的代码并返回新代码以替代原代码的函数,这意味着你可以向语言本身添加新的结构。一旦你能扩展语言,你就可以针对你的问题构建它。所以,在 Lisp 中,你不仅仅是在写程序,你是在为你的领域编写一种语言,然后在该语言中编写程序。
That matters a lot more now, because what makes a program valuable is the opinions behind it. And we’re heading toward a world where software companies let their users change the product themselves, since with an LLM that’s easy. So if a company builds a good opinionated domain language for its product, everything its users build on top of it will be much better, because they start from the company’s opinions and not from scratch. 这一点在现在尤为重要,因为程序的价值在于其背后的理念。我们正走向一个软件公司允许用户自行修改产品的世界,因为有了 LLM,这变得非常容易。因此,如果一家公司为其产品构建了一种优秀的、具有特定理念的领域语言,那么用户在其之上构建的一切都会更好,因为他们是基于公司的理念而非从零开始。
Take an ERP. Every company runs a little differently, so almost everyone ends up needing to change it. But if the ERP is written in its own domain language, you can just ask an LLM to make the change in that language. The change will naturally follow the domain language’s underlying opinions, so it fits the product instead of breaking it. 以 ERP 为例。每家公司的运营方式略有不同,因此几乎每个人最终都需要对其进行修改。但如果 ERP 是用其专属的领域语言编写的,你只需让 LLM 用该语言进行修改即可。这种修改会自然地遵循领域语言底层的理念,从而契合产品,而不是破坏它。
And it’s not just better, it’s also cheaper. Lisp programs are often much more concise because macros let you abstract away recurring patterns and make them part of the language itself. So the bigger the program gets, the bigger the difference. In my own experience the apps I’ve built in Common Lisp end up about six to seven times shorter than the Python versions. 这不仅更好,而且更便宜。Lisp 程序通常要简洁得多,因为宏允许你抽象出重复的模式,并将其作为语言本身的一部分。因此,程序越大,这种差异就越明显。根据我的经验,我用 Common Lisp 构建的应用程序最终比 Python 版本短六到七倍。
For LLMs, less code means fewer tokens, and tokens are what you pay for so you spend less on development. It also means a bigger portion of your program can fit in the LLM’s context window. If your LLM has your entire program in its context window then it has a complete view of your intent, which leads to it making better decisions. In my experience a lot of LLM bugs stem from it changing one piece of my program without seeing the rest. So with Common Lisp that happens less often. 对于 LLM 来说,更少的代码意味着更少的 Token,而 Token 是你需要付费的,因此开发成本更低。这也意味着你的程序有更大一部分可以放入 LLM 的上下文窗口中。如果 LLM 的上下文窗口中包含了你的整个程序,它就能完整地理解你的意图,从而做出更好的决策。根据我的经验,许多 LLM 的 Bug 源于它在修改程序某一部分时没有看到其余部分。因此,使用 Common Lisp 这种情况发生的频率更低。
Common Lisp is an ANSI standard and it hasn’t been updated since 1994. I like this feature. And going back to our ERP example, if your users change the product themselves, that’s exactly what you want since the language underneath never moves and nothing they build on top of it ever breaks. Common Lisp 是一个 ANSI 标准,自 1994 年以来就没有更新过。我喜欢这个特性。回到我们的 ERP 例子,如果用户自行修改产品,这正是你想要的,因为底层的语言从未改变,他们在上面构建的任何东西都不会损坏。
When you write a program in Common Lisp you often won’t be able to find a library you need. Quicklisp, the main Common Lisp package manager, has a couple thousand projects while npm has millions. But I don’t think that’s a problem anymore. Most programs today depend on millions of lines of code from packages that keep getting compromised. You don’t want that in yours. Also, with an LLM you could just write the part you need yourself or port the whole library — and LLMs seem to be really good at porting code. 当你用 Common Lisp 编写程序时,你经常会找不到所需的库。Common Lisp 的主要包管理器 Quicklisp 只有几千个项目,而 npm 有数百万个。但我认为这不再是个问题。如今大多数程序都依赖于数百万行不断被曝出漏洞的包代码。你肯定不希望你的程序包含这些。此外,有了 LLM,你可以自己编写所需的部分,或者移植整个库——而且 LLM 在移植代码方面似乎非常出色。
Lastly, I’m seeing now that a lot of people are programming now in the hope of building a business. An obvious objection to building products in Common Lisp is that you’ll have a hard time finding engineers since so few people know how to program in it. But I don’t think that really matters now. If you want to build a successful company you want to hire the best technical people: the ones who are really good at learning new things. So in your coding interviews just make them learn Common Lisp, and there you go. You’ll see how fast people pick things up, and the ones who do well will probably keep learning it and get really good at it. 最后,我发现现在很多人编程是为了创业。使用 Common Lisp 构建产品的一个明显反对意见是,由于很少有人会用它编程,你很难找到工程师。但我认为这现在并不重要。如果你想建立一家成功的公司,你需要聘请最优秀的技术人才:那些非常擅长学习新事物的人。所以,在面试中让他们学习 Common Lisp 就行了。你会看到人们掌握新知识的速度有多快,而表现出色的人很可能会继续深入学习并精通它。
In conclusion, next time you want to write a program use Common Lisp. 总之,下次你想写程序时,试试 Common Lisp。