Skip to content

设计原则

总原则

Qlang 的设计标准不是“理论上最纯”,而是“在大型工程里最稳、最顺、最可持续”。下面这些原则会约束语法、类型系统、运行时、工具链和生态决策。

1. 小核心,大能力

语言核心应当尽量小。复杂能力优先通过以下路径获得:

  • 编译器推断
  • 标准库抽象
  • 工具链自动化
  • 明确分层的 unsafe 扩展

这意味着 Qlang 不会一开始就引入过多表面特性。每增加一个语法构造,都要回答三个问题:

  1. 是否显著降低真实工程样板?
  2. 是否能保持语义一致性?
  3. 是否会给编译器、LSP 和格式化器带来可控复杂度?

2. 默认安全,显式越界

所有危险边界都应显式化:

  • 空值风险通过 Option[T] 建模
  • 错误通过 Result[T, E] 建模
  • 原始指针、手工布局、FFI 不安全段必须放在 unsafe
  • 并发共享必须通过受控容器或 actor 边界实现

Qlang 的哲学不是“禁止你做危险的事”,而是“危险必须有成本,并且成本看得见”。

3. 简单的表面语法,强约束的语义

语法选择上尽量走熟悉路径,减少学习成本:

  • C 家族块结构与花括号
  • fnstructenumtraitimpl 这些主流标识
  • 表达式导向,但不搞过度技巧化写法

真正拉开差距的是语义层:

  • 默认值语义
  • 自动借用与移动推断
  • 穷尽匹配
  • 发送性和共享性检查
  • 类型和效果的边界控制

4. 工程可迁移优先于语言炫技

新语言必须能进入旧系统,而不是要求旧系统迁就它。因此:

  • 包、模块、链接、测试、文档、LSP 必须同步规划
  • FFI 和 ABI 策略先于宏、反射和花哨语法
  • 错误信息和迁移工具先于“高级特性大全”

5. 约束要能解释

凡是限制用户的地方,都必须能说清楚为什么存在。例如:

  • 为什么默认不可变:为了压低别名和竞态复杂度
  • 为什么共享可变状态需要容器:为了给编译器稳定的数据竞争模型
  • 为什么公共 API 需要更明确的类型签名:为了改善阅读性、文档性和增量编译缓存命中

如果一条限制无法解释成工程收益,它就不该进入语言核心。

6. 诊断体验是语言特性的一部分

对于现代语言来说,报错质量不是锦上添花,而是主能力。Qlang 需要从架构层保证:

  • 每个语义阶段都有稳定的 span 和错误码
  • 错误能给出修复建议,而不是只说“不允许”
  • LSP 与编译器共用语义数据库,避免两个真相源
  • 重构、跳转、补全和语义检查来自同一套中间表示

7. 分阶段成长,而不是一次性做满

Qlang 应当从一开始明确 P0、P1、P2 边界:

  • P0:先把语言主骨架、LLVM 后端、C FFI、LSP 核心和标准库地基做稳
  • P1:再补 Rust 互操作、并发模型、文档生成、测试和包管理增强
  • P2:最后考虑更高阶的效果系统、宏、反射、C++ 深互操作和高级优化

这能避免把路线图做成一张漂亮但无法落地的海报。

8. 借鉴成熟语言,但不复制历史包袱

Qlang 应明确向现代语言学习:

  • 向 Kotlin 学表达力、空安全、数据建模和 smart cast
  • 向 Go 学统一工具链、项目纪律和小接口哲学
  • 向 TypeScript 学控制流收窄、编辑器体验和项目图管理

但学习不等于照搬。凡是会破坏系统语言目标的能力,例如默认结构类型、过度魔法化 DSL、弱错误约束,都不应直接进入语言核心。

Qlang research repository