F*:用证明驱动编程,把规格写进类型里
该项目围绕「A Proof-oriented Programming Language. [fstar-mode.el]: Emacs mode for F* [fstar-vscode-assistant]: VS Code plugin for F* More details on [editor support] are available on the [F\* wiki].」构建,适用于实际场景的开源实践,提供可复用的工具链与集成方式。
秒懂
- 它是什么?
- F* 是一门面向证明的编程语言,把程序与数学证明写在同一个源文件里。本文基于官方文档与仓库信息,拆解它的验证机制、执行路径、编辑器支持,以及它适合谁、不适合谁。
- 适合谁用?
- F* 适合需要把安全属性写进代码语义里的团队,尤其是做密码学协议、系统级并发或形式化验证的研究者。它不适合只想快速写业务逻辑的人,因为验证开销和类型复杂度都是实打实的。
- 能商用吗?
- 可以。Apache-2.0 是宽松许可证:你可以使用、修改并销售基于它的软件,只需保留版权和许可证声明。
- 还在维护吗?
- 在维护。仓库最近一次提交在 1 天前。
- 用什么语言写的?
- 主要是 F*(依据 GitHub 的语言统计)。
以上回答依据项目的 GitHub 数据(最近同步于 2026年9月14日)和我们的分析,不构成法律意见。
开源项目深度解析
它解决的是“证明与代码分家”的问题
大多数语言的类型系统只能表达数据形状,不能表达行为约束。F* 把这两件事合并了。它是一门依赖类型语言,类型里可以写函数的前置条件、后置条件、循环不变量,甚至完整的数学命题。验证器会检查这些条件是否成立,不成立就拒绝编译。这解决的是安全关键代码里最常见的痛点:规格写在文档里,实现写在代码里,两者靠人来同步,而人会犯错。F* 的目标用户是那些愿意为正确性付出额外开发成本的人,比如密码学实现、协议栈、并发原语。它不是给普通业务开发者准备的,文档里没有一句面向“快速上线”的话。
验证机制:类型即命题,SMT 求解器当裁判
F* 的核心机制是依赖类型加 SMT 自动求解。你写的每个函数都可以带一个 refine 类型,比如“返回的整数大于输入”,验证器会把这个条件转成逻辑公式,交给底层的 SMT 求解器去证明。证明不通过,代码就通不过检查。这与 Coq 那种手动构造证明项的方式不同,F* 尽量把证明自动化,你只需要在关键点给出 hint 或引理。代价是调试证明失败时你得理解 SMT 求解器的输出,这经常不直观。README 里没有详细展开 SMT 细节,但 wiki 有额外技术文档,说明这部分复杂度是官方承认的。另外,F* 默认只验证不执行,这一点必须记住:你写的是程序加证明,但运行前得先提取成别的语言。
运行路径:验证之后还要提取,默认不执行
这是 F* 最容易让人误解的地方。默认情况下,fstar 命令只检查代码的正确性,不生成可执行文件。要真正跑起来,你得用 --codegen OCaml 或 --codegen FSharp 把代码提取成 OCaml 或 F#。这意味着你的部署链路里多了一层翻译,而且提取后的代码行为必须与 F* 语义一致,这本身是个需要验证的点。对于并发和命令式代码,F* 内置了 Pulse 这个 DSL,它可以提取到 C 或 Rust,但走的是 KaRaMeL 工具链,不是 F* 直接支持。另外还有一个 ASM 风格的深层嵌入 DSL,可以提取到汇编,用的是 Vale 工具。所以 F* 不是单一语言,而是一个验证前端加多条提取后端的组合。选型时你得先想清楚最终产物是什么语言,这直接决定工具链的复杂度。
编辑器支持:Emacs 和 VS Code 是主力,AI 插件是新方向
官方 README 明确说 Emacs 和 VS Code 有最完整的支持,包括语法高亮、补全、导航和增量交互式开发。fstar-mode.el 是 Emacs 的扩展,fstar-vscode-assistant 是 VS Code 插件。交互式开发的意思是你可以逐步发送代码片段给验证器,实时看到证明状态,这对调试证明很重要。另外,README 提到 AI 智能体(如 Copilot CLI 和 Claude Code)用 F* 和 Pulse 时,官方推荐安装 proof-copilot 插件,它提供针对语言特性的 agents 和 skills。这个插件在仓库里,但 README 没有说它的成熟度,只是推荐。如果你依赖 IDE 的智能提示,F* 的体验会比主流语言粗糙,因为类型信息复杂,补全的准确度取决于工具维护者的跟进速度。
一个真实的限制:旧版本不维护,问题必须到 master 复现
F* 的发布节奏是每周一个版本,从 v2026.08.09 到 v2026.08.23 间隔七天。但 README 里有一句很硬的话:不维护旧版本。报告 issue 之前,官方要求你先在在线编辑器或 GitHub 源码上确认问题在 master 分支仍然存在。这意味着如果你锁定了某个旧版本,遇到 bug 只能自己修或升级,没有长期支持通道。这对生产项目是个风险,因为每周升级可能带来破坏性变化。另外,官方推荐用在线编辑器(fstar-lang.org/run.php)来复现问题,说明本地构建可能比较麻烦,或者版本差异导致问题难以定位。如果你需要稳定基线,F* 的发布策略可能不适合你,除非你愿意自己维护 fork。
替代方案:Coq 与 Lean 的差异在证明自动化程度
与 F* 最接近的替代是 Coq 和 Lean,它们都是依赖类型证明助手。区别在证明方式:Coq 要求你手动构造证明项,通常用 tactic 逐步引导,自动化程度低但可控性强;Lean 也依赖 tactic,但它的数学库和元编程能力更丰富。F* 则把验证尽量推给 SMT 求解器,你写的是程序本身,证明条件自动生成,失败时才介入。这个差异决定了使用体验:F* 更接近“带检查的编程”,Coq 更接近“写证明的数学”。如果你的需求是验证算法性质而不需要提取到 C 或汇编,Coq 可能更合适,因为它的提取机制更成熟。但如果你要的是在写代码的同时验证,并且最终要 OCaml 产物,F* 的路径更直接。
采用前的检查清单:许可证、文档与社区支持
F* 采用 Apache-2.0 许可证,商用友好,没有 copyleft 限制,这点对嵌入式场景很关键。官方文档包括一本在线书《Proof-oriented Programming In F*》,提供 PDF 和浏览器内交互教程,这是学习的主要入口。社区沟通在 Zulip 论坛,旧 Slack 已废弃,说明项目在主动迁移。维护方面,每周发布说明项目活跃,但“不维护旧版本”意味着升级成本是你必须计算的。贡献指南在 CONTRIBUTING.md,但 README 没提贡献流程细节。最后,F* 的验证能力很强,但它的学习曲线和工具链复杂度是真实的。如果你只是想验证一个算法,在线编辑器足够;如果你要生产部署,先确认提取后的 OCaml 代码能被你的构建系统接受。
编辑结论
F* 适合需要把安全属性写进代码语义里的团队,尤其是做密码学协议、系统级并发或形式化验证的研究者。它不适合只想快速写业务逻辑的人,因为验证开销和类型复杂度都是实打实的。采用前先确认三件事:一是你的代码能否接受 OCaml 或 F# 作为最终产物,F* 默认不编译,提取路径决定运行方式;二是团队是否愿意承担学习依赖类型和 SMT 证明的曲线,官方教程 PDF 和在线练习是起步的唯一官方材料;三是检查你依赖的库是否已有 F* 绑定,否则从零建模的工作量可能超过项目本身。如果你不需要可执行代码,只想验证算法性质,F* 的在线编辑器可以零安装试跑,这比本地构建更值得先试。
社区笔记