Riddle 的设计取向
Riddle 想验证一个问题:既然 GC 已经负责回收堆内存,移动语义、借用检查和确定性析构还有保留的价值吗?
Riddle 的答案是保留,但把标注降到最低。
Rust 用生命周期参数把引用的有效期写进类型。这套机制能表达的东西远超日常需要,代价却落在每一次编译和每一次编辑器请求上:组合子风格的代码要做大量类型体操,检查器要反复求解约束,泛型实例化还会带来子类型相关的问题。真正写业务代码时,需要三个以上生命周期字面量的场合很少。既然收益有限,Riddle 干脆不提供生命周期语法,改由编译器分析引用来源:引用可能在当前栈帧之外继续存活时,值被提升到 GC 堆,所有权和借用规则本身不变。
Go 的并发模型和工具链体验值得借鉴,但它对底层的处理是另一个极端:语言刻意保持简单,需要接触内存布局或调用 C 时只能依赖不安全的后门,标准库也因此留下了不少补丁式设计。Riddle 选择把底层能力显式隔离在 unsafe、原始指针和 FFI 里,其余部分保持静态检查。
组合起来,Riddle 的取舍是:
- 值默认移动,
Copy类型按复制处理; - 引用分共享与可变,借用冲突在编译期报错;
Drop在所有者结束时确定性执行,不依赖 GC 时机;- 存储位置由逃逸分析决定,按需提升到保守式非移动 GC 堆;
- 共享行为用 trait + impl 表达,没有类继承。
不提供的东西同样是设计的一部分:没有生命周期参数、没有显式 Box/Rc/Arc、没有异常、没有类。这些选择会在对应章节里反复出现。
Riddle 目前是单线程语言,线程、异步和网络都还没有实现。除此之外,语法和 ABI 仍会在版本之间变化。