先说结论:我花了大概 1 个月,借助 AI 以 Vibecoding 的方式,做了一门新语言,叫 EzLang。
它现在还不是一门“可以放心上生产”的语言,更准确地说,它是一个能跑、能编译、能写 demo、能看到方向的语言实验项目。但我确实把一整套东西从 0 搭起来了:语法、编译器、LLVM IR、CLI、标准库、LSP、VS Code 插件、WebAssembly、Android/iOS UI 绑定雏形,以及一堆测试。
所以这篇文章不是“我发明了未来编程语言”的宣言,而是一次比较真实的复盘:一个普通开发者,在 AI 辅助下,为什么会开始造一门语言,中间踩了哪些坑,以及这个项目后面还需要什么样的人一起把它做下去。
起因:我只是想试试“语言设计能不能 Vibecoding”
最开始的动机其实很朴素。
过去写业务、写工具、写框架时,我经常会冒出一些“不如语言层面就支持”的想法。比如:
- 能不能默认值语义,少一点到处共享可变状态的心智负担?
- 能不能有 Arena 风格的内存模型,但又不要把使用体验做得太硬核?
- 能不能把并发写得像同步代码,而不是一层层
async/await传染? - 能不能同时面向 native、WebAssembly、移动端?
- 能不能让标准库和工具链一开始就作为语言的一部分,而不是后面补?
这些想法单独看都不新。很多成熟语言都在不同方向上做过更深入、更严谨的探索。
但我当时真正好奇的是:如果今天有 AI,当一个人想从 0 做一门小语言时,边界到底在哪里?
于是 EzLang 就开始了。
我的工作方式大概是:我负责判断方向、拆问题、看 diff、跑测试、砍掉不合理抽象;AI 负责大量重复实现、文档初稿、测试样例、边界条件补全。听起来很美好,但实际过程里,AI 会很自信地写错,尤其在编译器这种地方,错得还挺像真的。
EzLang 大概是什么
EzLang 是一门表达式优先、默认值语义的系统编程语言实验。
一个最小例子大概长这样:
from "std/io" import { println };
let name: Str = "EzLang";
println(msg = "Hello {{name}}");
它目前有这些设计方向:
- 表达式优先:变量、控制流、
match、函数调用等尽量可以自然组合。 - 类型系统:支持泛型、可选类型、联合类型、结构体、类型别名、
List/Dict等。 - 值语义 + Arena:默认按值复制,临时内存由 Arena 管理。
- Flow 并发:用
flow {}、parallel {}、race(pl)表达并发语义,尽量保留同步代码的写法。 - 外部 ABI:通过
extern和declare调 C、JS 或平台库。 - 跨平台目标:native、emcc/WebAssembly、Android、iOS 都有不同程度的支持。
- 工具链:有
ez build、ez run、ez test、ez fmt、LSP 和 VS Code 插件。
这不是说这些能力都已经成熟。恰恰相反,它们很多还处于 demo 或最小可用状态。但至少现在已经不是只停留在 README 里的幻想了。
最难的不是写代码,是不断发现“语言设计没有小改动”
做业务系统时,一个字段设计错了,大不了迁移一下。做语言不一样。
你今天随手加一个语法糖,明天它就会影响 parser、语义分析、类型推断、codegen、formatter、LSP、文档和测试。
比如字符串插值。一开始只是想支持:
"Hello {{name}}"
很快就会变成:那 {{first + last}} 要不要支持?插值表达式类型必须是 Str,还是自动调用 toString?如果报错,错误位置要指向字符串内部还是整行?LSP hover 怎么办?formatter 能不能保持原样?
再比如 parallel。语义上我希望它像同步代码一样好理解,但实现上又要区分:
- 是否在
flow内; - 是否零捕获;
- 返回值是不是
I32; - native 目标和 emcc 目标 runtime 完全不同;
- 读取结果时要不要自动 join;
- Flow 退出时未读取任务如何处理副作用。
语言里很多设计都是这样:看起来只是“加个特性”,实际上是在同时改一条生态链。
AI 帮了很多,也坑了很多
Vibecoding 最大的好处是,它让一个人可以快速推进大量工程面工作。
比如标准库 API、测试样例、文档翻译、CLI 子命令、VS Code 插件骨架,这些如果全手写,速度会慢很多。AI 在这类“有明确局部目标”的任务里很有用。
但 AI 也有明显问题:
- 它很容易过度设计,写出看起来很完整、实际没必要的抽象。
- 它会在编译器里编出不存在的 ABI。
- 它会修一个测试,顺手破坏另一个语义。
- 它会写文档时把“未来目标”说成“当前已支持”。
- 它对跨平台细节特别容易自信,比如 emcc、Android NDK、iOS SDK 这些边界。
所以这个项目里最重要的不是“让 AI 写”,而是“人要不断收缩问题、跑测试、删掉假正确”。
我越来越觉得,Vibecoding 不是降低工程判断要求,而是把工程判断的密度提高了。你不一定每行都亲手敲,但你必须更频繁地判断:这个东西是不是真的对?是不是过度?是不是和现有语义一致?
目前我觉得 EzLang 有意思的地方
第一,默认值语义 + Arena 这条路我还挺喜欢。
很多语言要么把内存交给 GC,要么把生命周期做得很显式。EzLang 目前尝试的是另一种手感:多数值默认复制,临时对象走 Arena,作用域结束回收。它不一定适合所有场景,但对于很多系统工具、小型运行时、编译期明确的数据结构,我觉得很有探索价值。
第二,Flow 并发 是一个想继续深挖的方向。
我不太想把并发写成到处传染的语法噪声。EzLang 现在的目标是:用户写接近同步的代码,runtime 在不改变可观察行为的前提下调度阻塞点。这个方向当然很难,现在也只是初版,但它是我个人最想继续做的部分。
第三,工具链从一开始就一起做。
这个项目不只是一个 parser demo。现在已经有 CLI、测试、格式化、LSP、VS Code 插件、标准库文档。哪怕很多地方还粗糙,但“语言不只是语法”的意识是从第一天就放进去的。
第四,跨平台不是后补的口号。
现在 native、emcc、Android、iOS 都在设计里有位置。Web UI、Android UI、iOS UI 都有低层绑定文档和部分桥接实现。它们还远远不是成熟框架,但这让语言的边界从一开始就不只停在命令行程序上。
但它的问题也非常多
必须诚实地说,EzLang 现在就是 demo 状态。
它的劣势也很明确:
- 编译器还不成熟,很多语义后面可能会调整。
- 性能没有严肃 benchmark,不能拿来吹。
- 标准库覆盖面看起来大,但不少模块还只是基础能力。
- Flow runtime 还很早期,native 事件源式调度没有完整接入。
- 移动端 UI 包是底层绑定,不是成熟 UI 框架。
- 语法设计还需要更多真实代码验证。
- 文档虽然补了中英文,但后续维护压力会很大。
- 生态为零,除了我自己,没有真正用户。
所以如果你问“我能不能拿它写生产项目”,我的回答是:现在不建议。
但如果你问“这是不是一个值得参与的语言实验”,我觉得是。
我希望什么样的人来一起做
如果你对下面任何一块感兴趣,都欢迎来看看:
- 编译器前端、语义分析、类型系统;
- LLVM IR/codegen;
- runtime、Arena、Flow 调度;
- WebAssembly / Emscripten;
- Android NDK / JNI;
- iOS / Objective-C runtime / UIKit bridge;
- 标准库设计;
- LSP、formatter、VS Code 插件;
- 文档、教程、示例项目;
- 语言设计讨论。
我不希望它变成一个“为了造轮子而造轮子”的玩具仓库。更理想的状态是:把它当成一个公开的语言实验场。可以讨论语义,可以推翻设计,可以写测试,可以做小 demo,也可以专门来挑刺。
挑刺其实很重要。语言项目最怕作者自嗨,越早被真实使用和质疑,越容易长出正确的形状。
最后,求个 star
EzLang 目前还很小,也很不成熟。
但过去这 1 个月,我确实把一个模糊的想法做成了一个能跑起来的项目。它有编译器,有标准库,有工具链,有文档,有一些跨平台尝试,也有一堆还没填完的坑。
如果你觉得这个方向有意思,欢迎来 GitHub 看看,提 issue,提 PR,或者单纯点个 star 支持一下:
一个 star 对成熟项目可能只是数字,对这种早期语言实验来说,至少能说明:这事不是只有我一个人在自言自语。
最后的最后
失业快 1 年了, 快没钱花了, 有工作机会私我一下- -