过去一个月,我在做一门新的编程语言:EzLang。
它还不是一门成熟语言,也不是可以拿去生产环境替代 C、Rust、Go、Zig 的工具。更准确地说,它是一次语言设计实验:如果我们重新思考系统编程语言的默认体验,能不能让它既接近底层、足够快,又更容易理解、更容易维护,也更适合 AI 时代的人机协作?
这篇文章想讲的不是“我又发明了一门语言”,而是 EzLang 背后的几个判断。
系统编程不应该总是很沉重
系统编程通常意味着你要关心性能、内存、并发、平台差异、ABI、工具链,以及一堆看起来和业务无关但又绕不开的细节。
这些细节很重要。问题是,它们不应该在每一行代码里都压过你真正想表达的逻辑。
EzLang 想做的是:保留系统编程需要的能力,但尽量降低日常写代码时的心智负担。
它不是把底层细节藏起来,而是希望把常见的风险和重复劳动交给语言、编译器和工具链处理,让开发者写出来的代码更接近自己的意图。
少踩内存坑,也不牺牲速度
内存安全和性能经常被放在天平两端。
一边是足够快,但开发者需要随时警惕悬垂引用、重复释放、生命周期混乱等问题。另一边是更省心,但有时会付出运行时成本,或者失去对性能细节的掌控。
EzLang 目前探索的是另一种组合:默认值语义,加上 Arena 风格的内存模型,再配合显式的弱引用语义。
简单说,语言希望让常见的内存错误更难发生,同时仍然保留系统级性能的空间。
这不是一句已经完成的承诺,而是一个正在验证的方向。真正要把这件事做好,需要更强的逃逸分析、更好的错误提示、更多反例测试,以及大量真实程序的压力测试。
但这个方向本身是我很想继续探索的:能不能让内存安全变成默认体验,而不是每次写代码都要反复和自己确认?
一套代码,走向更多平台
今天的软件越来越难只活在一个平台里。
你可能想写一个本地工具,也想让一部分逻辑跑在移动端,甚至还想把它编译到 WebAssembly,放进浏览器或边缘环境里。
EzLang 的目标之一,是让同一套语言和标准库尽量覆盖更多运行环境:本地、移动端、WebAssembly。
这不意味着所有平台都能被完全抹平。平台差异永远存在。EzLang 更想做的是,把那些可以统一的部分统一起来,把必须暴露的差异清晰地暴露出来,减少重复实现和上下文切换。
代码应该读起来像人的意图
我很在意一件事:代码不仅要能运行,还要能被人接住。
EzLang 采用表达式优先的语法,控制流、数据结构、函数调用都尽量自然组合。函数调用也支持命名参数,让代码在很多场景下更像是在描述“我要做什么”,而不是要求读者不断回忆参数顺序。
一个很小的例子:
from "std/fmt" import { format, toString };
from "std/io" import { println };
struct Data {
val: I32;
};
const create = (seed: I32): Data => {
const d = Data(val = seed + 32);
return d;
};
const main = (): I32 => {
const created = create(seed = 10);
const copied = created;
const args: Str[] = [toString<I32>(value = copied.val)];
println(msg = format(template = "copied value={}", args = args));
return copied.val == 42 ? 0 : 1;
};
这里的目标不是炫技,而是让代码尽量直白:创建数据、复制值、格式化输出、返回结果。读者不需要先记住太多隐式规则,才能理解这段程序在做什么。
AI 能写,人也要接得住
现在大量代码已经开始由 AI 起草。这个趋势不会倒退。
但我越来越觉得,AI 写代码之后,真正重要的问题不是“AI 能不能生成”,而是“人类能不能审查、理解、修改、长期维护”。
如果一门语言对 AI 友好,却让人类很难看懂,那并不是一个好结果。AI 生成的代码越多,语言本身越应该鼓励清晰、显式、可推理的表达。
EzLang 的一些选择就是从这个角度出发的:
- 少一些隐藏魔法。
- 多一些能直接读懂的结构。
- 让调用关系、数据流和生命周期尽量清楚。
- 让生成出来的代码不只是“能跑”,也能被人接手。
我希望 EzLang 写出来的程序,即使第一版是 AI 起草的,人类也能快速进入状态,知道哪里能改、哪里不能改、为什么会这样运行。
工具链应该从第一天开始存在
很多语言实验一开始只关注编译器,工具链以后再说。
但开发体验不是附属品。格式化、项目初始化、运行测试、编辑器补全、跳转定义、诊断提示,这些东西会直接影响一门语言是否真的能被使用。
所以 EzLang 仓库里不只有编译器,也包含:
- CLI
- 格式化工具
- LSP
- VS Code 插件
- 项目初始化和依赖管理
- 中英文文档
这些东西现在都还很早期,但我希望从一开始就把“语言”和“使用语言的体验”放在一起设计。
现在它能做什么
EzLang 当前的实现比较传统:
.ez 源码 -> ANTLR 解析 -> 语义分析 -> LLVM IR -> 目标文件 / 可执行文件
编译器目前用 Python 编写,LLVM IR 生成基于 llvmlite。
目前已经有的能力包括:
- 解析和语义分析流程。
- 面向示例程序的 LLVM IR 生成。
ez init、ez build、ez run、ez test、ez fmt。- 结构体、泛型、可选类型、联合类型、函数类型、命名调用、类型别名。
extern "..." for target和declare形式的外部 ABI 调用。- 早期的
flow {}、parallel {}、race(pl)并发语义实验。 - 格式化、LSP、VS Code 插件、示例和双语文档。
还不成熟的地方也很多:
- 语言规范还不稳定。
- 内存安全模型还需要更严格的证明和测试。
- 错误提示比较粗糙。
- 运行时很小。
- 跨平台行为还不完整。
- 标准库更像设计地图,还不是成熟生态。
我希望 EzLang 成为什么
我希望 EzLang 最终是一门让人愿意写、愿意读、愿意维护的系统编程语言。
它应该足够快,能编译到更多平台;也应该足够清楚,让普通开发者、资深工程师和 AI 生成的代码之间可以顺畅协作。
它不追求用复杂概念证明自己高级,而是希望让开发者写系统程序时少一点紧绷,多一点确定感。
这条路还很长。现在的 EzLang 更像一个可运行的设计草图。
如果你对编译器、类型系统、内存模型、语言工具链,或者 AI 时代的编程语言设计感兴趣,欢迎看看这个项目,也欢迎直接提出尖锐意见。
我最想听到的反馈包括:
- 默认值语义加 Arena 内存模型是否值得继续走?
- 这种语法是否真的降低理解成本?
- 命名参数在系统语言里是优势还是负担?
- 哪些测试能让内存模型更可信?
- EzLang 应该优先编译哪类真实小程序?
比起一句“支持”,我更需要能打破假设的反馈。