Appearance
设计原则
总原则
Qlang 的设计标准不是“理论上最纯”,而是“在大型工程里最稳、最顺、最可持续”。下面这些原则会约束语法、类型系统、运行时、工具链和生态决策。
1. 小核心,大能力
语言核心应当尽量小。复杂能力优先通过以下路径获得:
- 编译器推断
- 标准库抽象
- 工具链自动化
- 明确分层的
unsafe扩展
这意味着 Qlang 不会一开始就引入过多表面特性。每增加一个语法构造,都要回答三个问题:
- 是否显著降低真实工程样板?
- 是否能保持语义一致性?
- 是否会给编译器、LSP 和格式化器带来可控复杂度?
2. 默认安全,显式越界
所有危险边界都应显式化:
- 空值风险通过
Option[T]建模 - 错误通过
Result[T, E]建模 - 原始指针、手工布局、FFI 不安全段必须放在
unsafe中 - 并发共享必须通过受控容器或 actor 边界实现
Qlang 的哲学不是“禁止你做危险的事”,而是“危险必须有成本,并且成本看得见”。
3. 简单的表面语法,强约束的语义
语法选择上尽量走熟悉路径,减少学习成本:
- C 家族块结构与花括号
fn、struct、enum、trait、impl这些主流标识- 表达式导向,但不搞过度技巧化写法
真正拉开差距的是语义层:
- 默认值语义
- 自动借用与移动推断
- 穷尽匹配
- 发送性和共享性检查
- 类型和效果的边界控制
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、弱错误约束,都不应直接进入语言核心。